
extern int foo(int); vs int foo(int);
Quote:
>>> 1. extern int foo(int);
>>> 2. int foo(int);
>>> ... is there a reason to use one over the other in the header file?
>>The latter means the same as the former, provided that there
>>is not a conflicting previous declaration.
>Does it mean anything different if there is? I don't see that they fail in
>different ways or circumstances. One curious case is that both:
>static int foo(int);
>extern int foo(int);
>and
>static int foo(int);
>int foo(int);
>are correct and declare foo as a static function. In this sort of case
>a static declaration must come first so:
Indeed, you are right:
6.1.2.2 Linkages of identifiers
If the declaration of an identifer for an object or
a function contains the storage class specifier extern, the
identifier has the same linkage as any visible declaration
of the identifier with file scope.
Quote:
>static int foo(int);
>extern int foo(int);
>static int foo(int);
>is fine, however:
Right, because all three declarations have internal linkage.
Quote:
>extern int foo(int);
>static int foo(int);
>is not.
Because it violates
6.1.2.2 Linkages of identifiers
If, within a translation unit, the same identifier
appears with both internal and external linkage, the behavior
is undefined.
Only ``extern'' has the magic linkage-inheriting property, ``static''
does not.
Quote:
>>The main reason to prefer the former is that it explicitly documents
>>the fact that the function will be provided elsewhere, but since
>>that's implied anyway, it's not a string reason.
>extern is a mixed bag with regards to being defined elsewhere, e.g.:
>extern int = 0;
>However this whole area is rather inconsistent.
It's very confusing. Firstly, the term ``external'' has two meanings, and
what's worse, they are mixed up in a related concept; an external declaration
is one which appears at file scope, whereas external linkage means linkage
across translation units. Now, the ``extern'' keyword is called a storage
class specifier, yet it really specifies linkage, since all object identifiers
that are declared extern have linkage, and all objects that have linkage
necessarily have static storage class. What's worse, ``extern'' does not
always specify external linkage; rather it causes linkage to be inherited from
a previous file-scope declaration. If no such declaration exists, only then
does it defaults to external. As if that wasn't bad enough, ``static'' is
overloaded to specify static storage class when applied to local variables,
and to specify internal linkage when applied to file-scope declarations. A
local static variable has no linkage, where a local extern variable has
linkage. Whew!
I really can't blame newbies for being mixed up.