C compiler ignores 'static' for declaration of struct
C compiler ignores 'static' for declaration of struct
In C, if I declare a structure like so:
static struct thing
int number;
;
and compile it (with gcc in this case), the compiler prints this warning:
warning: 'static' ignored on this declaration
[-Wmissing-declarations]
Why is this?
My intention in making the struct static would be to keep thing
out of the global namespace so that another file could declare its own thing
if it wanted.
thing
thing
@nicomp: so you're saying that a struct declaration, or any data type declaration for that matter, already has the behavior I want, that of not being in the global namespace, without the use of 'static', as long as it's not put in a header?
– Jacquen
Aug 29 at 22:51
The word
static
applies to the variable declared with it, not the type. For example: static struct timeval startw
, here startw
would be considered static not timeval
. Reference– whatthefish
Aug 29 at 22:55
static
static struct timeval startw
startw
timeval
Yes, I am saying that. You can't 'extern' a user-defined data type.
– nicomp
Aug 29 at 23:02
Is thing being declared in a header file?
– jwdonahue
Aug 29 at 23:55
3 Answers
3
Struct tags (and typedef names) have no linkage, which means they are not shared across translation units. You might use the term "private" to describe this. It is perfectly fine for two different units to define their own struct thing
.
struct thing
There would only be a problem if it was attempted to make a cross-unit call of a function with external linkage that accepts a struct thing
or type derived from that. You can minimize the chance of this happening by ensuring that functions with external linkage are only called via prototypes in header files (i.e. don't use local prototypes).
struct thing
You cant define the storage without defining the actual object.
static struct thing
int number;
obj1,obj2;
is ok and:
struct thing
int number;
;
static struct thing x,y;
You can't use static
on this way to control the linkage of a type like you could for a function or object, because in C types never have linkage anyway.
static
"Global namespace" isn't quite the term you want here. C describes names of objects and functions as having "external linkage" if the same name can be declared in different translation units to mean the same thing (like the default for functions), "internal linkage" if the same name can be redeclared within the same translation unit to mean the same thing (like declarations marked static
), or "no linkage" when a declaration names a different object or function from any other declaration (like variables defined within a function body). (A translation unit, roughly speaking, is one *.c file together with the contents of the headers it includes.) But none of this applies to types.
static
So if you want to use a struct type that's essentially private to one source file, just define it within that source file. Then you don't need to worry about another usage of the same name colliding with yours, unless maybe somebody adds it to a header file that the source file was including.
(And just in case a C++ user comes across this Q&A, note the rules for this in C++ are very different.)
I am amazed you attempted to cover this without mentioning scope. Linkage only applies to objects, not types. The OP is trying to hide a type, therefore they must control its scope.
– jwdonahue
Aug 29 at 23:59
@jwdonahue scope has nothing to do with this question. Also your claim "linkage only applies to objects" is incorrect; it applies to objects and functions. Nor is it clear why you try to point out that linkage doesn't apply to types, since that fact is the basis of most of this answer. Maybe you could write your own answer
– M.M
Aug 30 at 0:40
@jwdonahue Sure, in some cases it might help to define a struct within a function. But that's not an option if you want to use the struct in multiple functions and/or in parameter or return types of static functions.
– aschepler
Aug 30 at 0:47
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
It's a data type, it's only visible in the compilation unit where it's defined. That's why you put it in a header if you want to share it accross compilation units.
– nicomp
Aug 29 at 22:43