3

Sorry guys I know my english is bad, but i made examples so that my question is more clearer.

a.cpp

#include <iostream>

using namespace std;

void funcfoo(){
    cout << "test only" << endl;
}

int varfoo = 10;



b.cpp

#include <iostream>

using namespace std;

extern void funcfoo();

extern int varfoo;

int main(){

    funcfoo();

    cout << varfoo;

    return 0;
}

Then I compile it like this "cl b.cpp a.cpp"

My question is. How come when I remove the "extern keyword before void funcfoo()" it works fine, but when i remove the extern keyword before int var foo I get an error?

Coding Mash
  • 3,338
  • 5
  • 24
  • 45
user1628256
  • 319
  • 1
  • 3
  • 9
  • 2
    See http://stackoverflow.com/questions/2604202/c-extern-keyword-on-functions-why-no-just-include-the-header-file -- functions have external linkage by default; the keyword is redundant. – Wooble Aug 27 '12 at 17:02

4 Answers4

9

The issue is what each one of the lines of code means. int varfoo is a definition of a variable, while void funcfoo() is only a declaration. You can provide multiple declarations of an entity, but only one definition. The syntax to provide a declaration and only a declaration of a variable is by adding the extern keyword: extern int varfoo; is a declaration


3.1 [basic.def]/2 A declaration is a definition unless it declares a function without specifying the function’s body (8.4), it contains the extern specifier (7.1.1) or a linkage-specification25 (7.5) and neither an initializer nor a function body [...]

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • I think definition is like int varfoo = value;, then int varfoo; is declaration. Am I wroong? – user1628256 Aug 27 '12 at 17:04
  • int varfoo; <--- I think this is declaration not definition – user1628256 Aug 27 '12 at 17:09
  • @user1628256: Yes you are. `int varfoo;` is a definition without initialization, `int varfoo = value;` is a definition with initialization. – David Rodríguez - dribeas Aug 27 '12 at 17:09
  • int varfoo = value; <---- I think this one is declare then define. Am I wrong? – user1628256 Aug 27 '12 at 17:09
  • @user1628256 `int var;` <-- (definition), `var = 5;` <-- definition – David G Aug 27 '12 at 17:10
  • void funcfoo(){ cout << "test only" << endl; } <--- this is definition right? – user1628256 Aug 27 '12 at 17:12
  • It's a definition. Note: in global scope `int varfoo;` is with initialization. – Karoly Horvath Aug 27 '12 at 17:12
  • @KarolyHorvath: I am not sure about it. Variables with static storage duration are value initialized *before* any other initialization takes place, but that does not mean that the declaration has an *initializer* (it does not have one). – David Rodríguez - dribeas Aug 27 '12 at 17:23
  • so there is no declaration of a variable only a function? – user1628256 Aug 27 '12 at 17:24
  • @user1628256: `extern int varfoo;` **is** a declaration of a variable. – David Rodríguez - dribeas Aug 27 '12 at 17:24
  • ok lets just forget about extern, lets say we only have 1 .cpp file....so int varfoo you said it is definition right? – user1628256 Aug 27 '12 at 17:27
  • @user1628256: Yes, `int varfoo;` is a definition – David Rodríguez - dribeas Aug 27 '12 at 17:32
  • @David: why extern int varfoo; becomes a declaration? – user1628256 Aug 27 '12 at 17:39
  • @user1628256: Because that is how the language goes... read the quote from the standard in the answer. – David Rodríguez - dribeas Aug 27 '12 at 17:40
  • @user1628256 Before I answer that question, can you please accept this answer by clicking on the check mark next to it? It helps a lot. – David G Aug 27 '12 at 17:45
  • @user1628256: this is really *confusing*. I feel like I have split personality (with the other David). Anyway: what did you not understand from my last comment? Did you read the quote from the standard? – David Rodríguez - dribeas Aug 27 '12 at 17:51
  • @user1628256 You know that it's a declaration of a variable when you see: `int a;`. But it's a *definition* of a variable when you see: `a = 3` later on. You can also do this: `int a = 5;`. I am defining a new variable called `a` which I am initializing with the number 5. It doesn't matter if you see `extern` in front. If it's not being initialized, it is a declaration. – David G Aug 27 '12 at 17:54
  • @david I understand the declaration and definition with function. The quote from the standard that you post is about functions right?. What I dont get is about variable you said that "int varfoo" is definition, then extern "int varfoo" is declaration. I dont get why with extern it becomes a declaration. – user1628256 Aug 27 '12 at 17:55
  • @user1628256: No, it is about *declarations* in general. Note that the last sentence quoted contains: *and neither an initializer nor a function body*. You cannot provide an *initailizer* for a function, as you cannot provide a function body for a variable. – David Rodríguez - dribeas Aug 27 '12 at 17:57
  • @david "int varfoo is a definition of a variable" <--- you said this – user1628256 Aug 27 '12 at 17:58
  • @user1628256: Yes, `int varfoo;` **is** a **definition** and a **declaration**. `extern int varfoo;` is a **declaration** but not a **definition**. You keep asking the same once and again, but I don't understand what is it that confuses you. – David Rodríguez - dribeas Aug 27 '12 at 18:01
  • @david I already know the simple answer to my question "function names are made visible to the linker by default". But I got confuse with these definition and declaration. – user1628256 Aug 27 '12 at 18:02
  • Please take this conversation to the chat room. -- http://chat.stackoverflow.com/rooms/10 Or make your own – David G Aug 27 '12 at 18:02
  • you said int a; is a declaration then later a = 3 is definition. How come int varfoo is a definition i doesnt have a value. – user1628256 Aug 27 '12 at 18:10
  • @user1628256: You are confusing me (*David Rodriguez*) with someone else (*David*). I never said `int a;` is a *declaration* (it is, but it is also a *definition*). – David Rodríguez - dribeas Aug 27 '12 at 18:13
  • @david You know that it's a declaration of a variable when you see: int a;. But it's a definition of a variable when you see: a = 3 later on <-- coming from you – user1628256 Aug 27 '12 at 18:21
  • @david ok even though I dont get it I want to thank you. Im sleepy now so maybe thats part of the reason why I dont understand it. – user1628256 Aug 27 '12 at 18:29
  • @user1628256: Ignore that whole comment (note that the name of the commenter is 'David' --without any trailing last names...) That is misleading. `int a` **is** a definition, regardless of `= 3`. It is a declaration and not a definition if and only if `extern` is present and no initializer is present. – David Rodríguez - dribeas Aug 27 '12 at 18:53
  • @KarolyHorvath: The question was regarding the comment *Note: in global scope int varfoo; is with initialization*. There is a slight difference between there being an initializer and the variable being initialized. A variable with static storage duration will be value initialized, irrespective of the presence of an *initializer*. The declaration `int varfoo;` at namespace level does not contain an *initializer* even if it is guaranteed to be initialized to 0. – David Rodríguez - dribeas Aug 27 '12 at 19:53
  • @David Rodríguez - dribeas: ughmmhuhvomit.. I think you're saying the same thing, but with the correct terminology. Thanks. – Karoly Horvath Aug 27 '12 at 20:46
3

When you remove the extern from extern void funcfoo(); you are forward declaring it so you're code below will know what funcfoo() is. If you were to do that to a variable, you would actually be instantiating it and would conflict with your other file. Hence the extern is saying "it exists, trust me ;)" that it gets resolved from your other file.

MartyE
  • 636
  • 3
  • 7
0

Another way to think about it is that when you do int varfoo memory is allocated to hold the variable so it is both a definition and a declaration, when you do int foo() the function is declared but not defined so in a way the memory is not allocated. For functions the linkage is external by default so removing it doesn't matter but for the variable, if you say extern int varfoo the compiler will not allocate memory for it --it will assume that the variable is defined somewhere else.

0

I know this might be late, but I hope this helps in some way. Check the link below and it ll give an idea of what extern is and how it works.

http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/

Thank you

nikhs
  • 53
  • 8