1

I've tried the following code and got an error.

int main()
{
    //this will cause redefinition error
    extern int x;
    int x=2; 
}

I've seen some answers about extern such as

When to use extern in C++

Defining extern variable in main() vs. globally

and got an concept,but I am still wondering what does the compiler do in this case. Can extern be used(legal) inside some function?

update:

More specifically, since extern int x is just a declaration,why can't I define int x? Does the compiler take extern int x as a definition?

Community
  • 1
  • 1
lionel
  • 415
  • 1
  • 5
  • 14
  • 1
    `extern int x`; declares `x` with static storage duration; then `int x = 2;` attempts to declare `x` with automatic storage duration, that is the source of the error – M.M Jan 18 '17 at 07:13
  • @M.M Even though I don't exactly understand your meaning , I tried to use `static int x=2` rather than `int x=2` ,it still gives the error. – lionel Jan 18 '17 at 15:32
  • Then it is a different error, redeclaring `x` with different linkage – M.M Jan 19 '17 at 07:44

3 Answers3

0

Of course it can be used, don't define another x inside the function:

int main()
{
    extern int x;
    x=2; 
}
  • This will cause link error. int x cannot be resolved. – lionel Jan 18 '17 at 07:14
  • Obviously, you need to define x in another translation unit, else what was your purpose in using extern at all? –  Jan 18 '17 at 15:57
  • Yes, I know this kind of code makes no sense. I am just curious about how the compiler deals with this situation and the reason. – lionel Jan 19 '17 at 07:21
0

but I am still wondering what does the compiler do in this case. Can extern be used(legal) inside some function?

it can, but you must not redeclare variable as you have in your code. So this is a valid example:

int main()
{
    //this will cause redefinition error
    extern int x;
    x=2; 
}

int x; 
marcinj
  • 48,511
  • 9
  • 79
  • 100
  • I can't understand why this is a redefinition. `extern` is just a declaration. – lionel Jan 18 '17 at 07:17
  • @lionel you are right, its rather redeclaration (I will fix it). `int x=2;` is both declaration and definition, so if previously there was `extern int x;` in the same scope, then `int x=2;` will be a redeclaration. – marcinj Jan 18 '17 at 08:48
  • Redeclaration won't cause any problem. A variable can be declared several times but can only be defined once according to C++ Primer. – lionel Jan 18 '17 at 15:22
  • @lionel its more about the change of declared linkage of the variable, I think clang gives a better error message here: `error: non-extern declaration of 'x' follows extern declaration`. That means: `int x = 2` has no linkage, but befor `extern int x;` declared that `x` will have extern linkage. For a more formal explanation, I found this http://eel.is/c++draft/dcl.spec#dcl.stc-6, : `within a given scope, each declaration declaring the same variable name or the same overloading of a function name shall imply the same linkage` – marcinj Jan 18 '17 at 16:44
  • I get a little clearer about it. Then if I define `int x` in another cpp file and this local `extern int x` will link to it. As the same time, I can only use this `x ` in `main` function and cannot define another `int x` in the `main` scope. Am I right? – lionel Jan 19 '17 at 07:44
  • You can define another `int x` in main but it must be at different scope than the `extern int x`, for example : `int main() { extern int x; { int x=2; } } int x = 23; ` – marcinj Jan 19 '17 at 08:59
0

As the others have answered, yes, you can use it in your function as long as you don't declare another variable with that name.

To your question of what the compiler does, dreamlax's answer to the question you linked, handles it pretty well. The compiler doesn't need to do/know anything other than what it's type is so that it knows how it can be used. The linker will see that it's an extern and know that it needs to go find where it is actually declared.

This MSDN link provides more general info on externs and what Microsoft does in VS 2015.

Community
  • 1
  • 1
Taylor Price
  • 622
  • 1
  • 8
  • 21