extern int foo(int); vs int foo(int); 
Author Message
 extern int foo(int); vs int foo(int);

I've compiled a source file with main and a separate source
file with a int foo(int){  }  in it while using a
header file with both:

        1.  extern int foo(int);

and

        2. int foo(int);

as declarations. It does not seem to make a difference
either way. So is there a reason to use one over the
other in the header file?

art



Sat, 08 Jul 2000 03:00:00 GMT  
 extern int foo(int); vs int foo(int);


Quote:
>I've compiled a source file with main and a separate source
>file with a int foo(int){  }  in it while using a
>header file with both:

>    1.  extern int foo(int);

>and

>    2. int foo(int);

>as declarations. It does not seem to make a difference
>either way. So is there a reason to use one over the
>other in the header file?

An explanation of what the differences may potentially be is available
in the Rationale for ANSI C, Section 3.1.2.2.  In brief, the differences
occur in the model that is used for linkages of identifiers.  The
Rationale describes 4 models.

Common:
   Every object with external linkage creates a definition of storage.
   The combination of the modules results in definitions of the same
   name residing at the same memory address.  This is the model Dennis
   Ritchie had in mind when he designed C.

Relaxed Ref/Def:
   Appearance of "extern" in a declaration indicates a pure
   reference.  At least one definition of the object must exist.  Some
   implementations may ignore references to objects that are not used
   (UNIX model), which is recognized as a common extension to the C
   language.

Strict Ref/Def:
   Idem, except that only one definition is allowed.  Idem extension may
   apply.  This is the model specified in K&R and in the Base Document.

Initialization:
   Explicit initialization defines storage.  All other declarations are
   references.

ANSI C adopted a combination of the latter two models.  Thus for maximal
portability, use "extern" in your header files, and only one definition
among your translation units.

--

http://www.cs.wustl.edu/~jxh/        Washington University in Saint Louis

Quote:
>>>>>>>>>>>>> I use *SpamBeGone* <URL:http://www.internz.com/SpamBeGone/>



Sun, 09 Jul 2000 03:00:00 GMT  
 extern int foo(int); vs int foo(int);

Quote:

>I've compiled a source file with main and a separate source
>file with a int foo(int){  }  in it while using a
>header file with both:

>        1.  extern int foo(int);

>and

>        2. int foo(int);

>as declarations. It does not seem to make a difference
>either way.

For *function* declarations and definitions the extern keyword makes no
difference at all. It does of course make a difference for object
declarations and definitions.

Quote:
>So is there a reason to use one over the
>other in the header file?

For functions it is purely a case of which style you prefer. You could even
write:

extern int foo(int){  }

--
-----------------------------------------


-----------------------------------------



Sun, 09 Jul 2000 03:00:00 GMT  
 extern int foo(int); vs int foo(int);


Quote:

>An explanation of what the differences may potentially be is available
>in the Rationale for ANSI C, Section 3.1.2.2.  In brief, the differences
>occur in the model that is used for linkages of identifiers.  The
>Rationale describes 4 models.

Irrelevant. We are looking at a funtion declaration. In a function declaration,
a missing storage class specifier is treated as though 'extern' had
been written.

Quote:
>Common:
>   Every object with external linkage creates a definition of storage.

However, objects are not functions.

A function identifier with or without an 'extern' specifier has external linkage.
A function declaration with 'static' storage class has internal linkage.
Functions always have linkage, whereas it is possible for object names to have
no linkage---this is the case if they are automatic, or static locals.

Quote:
>ANSI C adopted a combination of the latter two models.  Thus for maximal
>portability, use "extern" in your header files, and only one definition
>among your translation units.

This advice is correct, of course. But it doesn't apply to function
declarations, from which the extern may safely be omitted.

Omitting the extern from object declarations will cause undefined behavior if
the declarations are included into more than one translation unit which are
then linked together. That's because you then have multiple definitions of the
same external identifier.

A file-scope object declaration with no storage class specifier has external
linkage by default, and is a *definition* if it has an initializer. If it has no
initializer, it is still a definition, albeit a ``tentative'' one: this means
that if, by the end of the translation unit, it is not re-declared with an
initializer, then it is as though it had been defined with an initializer of zero.

Even an extern object declaration is a definition if it has an initializer.
The *only* way to create an eternal object declaration that is not also a
definition (i.e. is a ``ref'' only, not a ``def'') is to use extern and omit
writing an initializer. This does not apply to function declarations, which
can only be definitions if they are written with a body.



Sun, 09 Jul 2000 03:00:00 GMT  
 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.

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.



Sun, 09 Jul 2000 03:00:00 GMT  
 extern int foo(int); vs int foo(int);

Quote:

> >So is there a reason to use one over the
> >other in the header file?
> For functions it is purely a case of which style you prefer. You could even
> write:
> extern int foo(int){  }

That is not a declaration, but a function definition, not suitable for
use in the header.


Sun, 09 Jul 2000 03:00:00 GMT  
 extern int foo(int); vs int foo(int);

Quote:

> I've compiled a source file with main and a separate source
> file with a int foo(int){  }  in it while using a
> header file with both:

>         1.  extern int foo(int);

> and

>         2. int foo(int);

> as declarations. It does not seem to make a difference
> either way. So is there a reason to use one over the
> other in the header file?

> art

  The keyword "extern" is optional in function prototype declarations.
It makes no difference to the compiler, it is there to tell you that
the function is defined somewhere else.

Kien.



Sun, 09 Jul 2000 03:00:00 GMT  
 extern int foo(int); vs int foo(int);


Quote:

>> >So is there a reason to use one over the
>> >other in the header file?
>> For functions it is purely a case of which style you prefer. You could even
>> write:
>> extern int foo(int){  }

>That is not a declaration, but a function definition, not suitable for
>use in the header.

Yes, I was just trying to point pointing out you can use extern with function
definitions. You're right that I should have made it clear that this isn't
something to be used in a header.

--
-----------------------------------------


-----------------------------------------



Sun, 09 Jul 2000 03:00:00 GMT  
 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:

static int foo(int);
extern int foo(int);
static int foo(int);

is fine, however:

extern int foo(int);
static int foo(int);

is 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.

--
-----------------------------------------


-----------------------------------------



Sun, 09 Jul 2000 03:00:00 GMT  
 extern int foo(int); vs int foo(int);


[snip]

Quote:
>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:

>static int foo(int);
>extern int foo(int);
>static int foo(int);

>is fine, however:

>extern int foo(int);
>static int foo(int);

>is not.

Seeing Lawrence explain something like this is like listening to
C{*filter*}te Green reading the shipping forecast.  It just gives you
a feeling of security and that all's right with the world.  (Except
that Lawrence doesn't get the giggles.)

Dogger, Fisher, German bite...

(With apologies to those outside BBC broadcasting range.)

John
--
John Winters.  Wallingford, Oxon, England.

The Linux Emporium - a source for Linux CDs in the UK
See < http://www.*-*-*.com/ ;



Sun, 09 Jul 2000 03:00:00 GMT  
 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.



Sun, 09 Jul 2000 03:00:00 GMT  
 extern int foo(int); vs int foo(int);

Quote:

> >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?

It used to, in some implementations.  (A previous static would
override.)

Quote:
> However this whole area is rather inconsistent.

Yes, that's due to inheriting existing practice,
which overloaded a lot of distinct concepts onto one terminology.
(Another lesson for future language designers.)


Sun, 09 Jul 2000 03:00:00 GMT  
 
 [ 12 post ] 

 Relevant Pages 

1. extern int table[] vs extern int *table;

2. int func(int) versus int func(int *) efficacy.

3. Why is extern int * buf != extern int buf[] ?

4. (int/int) != int

5. Calling int f(int (*f)(int)) like function in DLL from VB

6. How to do int func(int size,int matrix[][size])

7. main() vs int main() vs int main(void)

8. Conversion of signed long int to n-bit signed int and vs vs

9. extern char *foo vs. extern char foo[]

10. int **a vs. int *a[]

11. unsigned int vs signed int

12. short int vs int wrt to execution time

 

 
Powered by phpBB® Forum Software