9

Possible Duplicate:
Effects of the `extern` keyword on C functions

Ok, so for a few hours now I've read a lot about what the extern keyword means. And there is one last thing that is bugging me to no end that I cannot find any info about. As far as I understand the extern keyword basically tells the compiler that the variable or function is only a declaration and that it is defined somewhere, so it doesn't have to worry about that, the linker will handle it.

And the warning generated by the compiler (I'm using gcc 4.2.1) when typing this:

extern int var = 10;

supports this. With extern this should be a declaration only so it is not correct.

However, the thing that is confusing me is the absence of a warning or anything when typing this:

extern int func() {return 5;}

This is a definition, and it should generate the same warning, but it does not. The only explanation to this I was able to find here is that the definition overrides the extern keyword. However, following that logic why does it not override it when it is a variable definition? Or does the keyword have special meaning when used with variables?

I would be most grateful if someone explained this to me. Thank you!

Community
  • 1
  • 1
tompitt
  • 340
  • 1
  • 11

2 Answers2

5

The extern keyword indeed has special meaning only when it is used with variables. Using extern with function prototypes is entirely optional:

extern void foo(int bar);

is equivalent to

void foo(int bar);

When you declaring/defining a function, you have two options:

  1. Provide only a declaration (i.e. a prototype), or
  2. Provide a definition, which also serves as a declaration in the absence of a prototype.

With variables, however, you have three options:

  1. Provide only a declaration,
  2. Provide a definition with the default initializer: int var; without the = 10 part, or
  3. Provide a definition with a specific initializer: int var = 10

Since there are only two options for functions, the compiler can distinguish between then without the use of extern keyword. Any declaration that does not have a static keywords is considered extern by default. Therefore, the extern keyword is ignored with all function declarations or definitions.

With variables, however, the keyword is needed to distinguish between the #1 and the #2. When you use extern, it's #1; when you do not use extern, it's #2. When you try to add extern to #3, it's a warning, because it remains a definition, and the extern is ignored.

All of this is somewhat simplified: you can provide declarations several times in the same compilation unit, and you can provide them at the global scope or at a block scope. For complete details, check section 6.7.9 5 of the C standard.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • The statements about object (not variable) declarations are incorrect. At file scope: `int x;` is a tentative definition of an object with external linkage, `extern int x;` is a declaration of an object with external linkage, `int x = 3;` and `extern int x = 3;` are both definitions of an object with external linkage. At block scope: `int x;` is a definition of an object with no linkage, `extern int x;` is a declaration of an object with external linkage, `int x = 3;` is a definition of an object with no linkage, and `extern int x = 3;` is not allowed, by C 2011 6.7.9 5.… – Eric Postpischil Feb 03 '13 at 13:44
  • The above presumes each declaration is the first time the identifier appears at that scope. Otherwise, there are complications. For example, `static int x; extern int x;` is permitted, and the latter `x` is the same as the former `x`. Also, although some compilers emit a warning for `extern int x = 3;` at file scope, it is explicitly shown as valid in the example at C 2011 6.9.2 4. – Eric Postpischil Feb 03 '13 at 13:46
3

However, following that logic why does it not override it when it is a variable definition? Or does the keyword have special meaning when used with variables?

The difference between variables and functions is that

void foo();

is a function declaration, but

int i;

is a variable definition.

If you have the variable definition in multiple files, then the compiler will generate the storage for that variable multiple times (and most likely you'll get a linker error). This is not the case for functions.

  • 1
    I think it's most confusing when we have `extern int x = 1;` which looks like both a declaration and a definition with an initializer. – Alexey Frunze Feb 03 '13 at 12:04
  • At file scope, `int i;` is a tentative definition, not a definition, and it neither generates storage multiple times nor causes a link error. – Eric Postpischil Feb 03 '13 at 14:02