16

Consider the code:

#include <stdio.h>

int x;

int main (void) 
{ }

The value of x is 0 inside main. But why is that? I have not declared it to be static. Or is it assumed static as it is outside a function?

If the above is true, how does it make it different from an extern?

Kanishk
  • 235
  • 1
  • 3
  • 6
  • Can you clarify your question about `extern`? – John Weldon Feb 24 '11 at 20:31
  • If I want to declare an external variable, isn't it done in the same way? – Kanishk Feb 24 '11 at 20:32
  • The difference between this and an extern is that an extern is external and this isn't. – David Heffernan Feb 24 '11 at 20:32
  • 2
    This subject is very frequently misunderstood and there seems to be a dearth of good questions with good answers relating to it on SO. – nmichaels Feb 24 '11 at 20:48
  • You might find [this](http://stackoverflow.com/questions/534735/internal-static-variables-in-c-would-you-use-them#535012) and [this](http://stackoverflow.com/questions/1856599/when-to-use-static-keyword-before-global-variables#1856642) and [this](http://stackoverflow.com/questions/1433204/what-are-extern-variables-in-c) useful. – nmichaels Feb 24 '11 at 23:12

7 Answers7

23

It's neither static nor extern. It's a variable visible for the compilation unit it's in, and additionally will be visible from all compilation units that declare x to be an extern variable.

Why am I saying it's neither static nor extern?

If it was extern, then, there must be a different compilation unit with x declaration on it. Clearly this is your only compilation unit.

If it was static then, no extern reference would be allowed to x variable defined in this compilation unit. We know that we could easily declare an extern variable to this x declared here.

Why is 0 assigned to x? Because, in C, all global variables initialize to 0. It says so in 6.7.8 (10) of the C99 standard.

Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
6

When we say that variables of "static storage duration" are initialized to 0 implicitly, we don't mean that you need to put the "static" keyword in front of them.

"static storage duration" merely is a specific kind of storage duration for objects that says that their storage lasts for the complete duration of the program. This kind of storage duration is used for variables declared at file scope (like your variable) and local static variables.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
3

It's not static. It's global. You can declare it extern in a different compilation unit, but space will be allocated for it in this one. Globals are always initialized to 0 if they aren't given initializers, by the way.

nmichaels
  • 49,466
  • 12
  • 107
  • 135
  • So when I call it another compilation unit using the keyword `extern`, it makes it an external variable there, but for this file, it is global. Right? – Kanishk Feb 24 '11 at 20:41
  • @Kanishk: It's global in both files, it's just that the `extern` declaration for it in the other file doesn't cause any space to be allocated. It gets the address from the linker, which gets the address from this file. – nmichaels Feb 24 '11 at 20:42
3

6.2.2/5: "If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external."

That's linkage, though, not scope. Your declaration of x would have file scope either way. static and extern don't affect scope. It's initialized to 0 because x has static storage duration (see 6.2.4/3 and /5).

In general you also have to be aware of 6.2.2./4:

For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration.

So declaring with extern is not quite the same as declaring with no storage-class specifier. In your example there is no prior declaration, though.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • The standard is the holy grail, in another question I asked before, people were quoting the standard. Thanks though :-) – Kanishk Feb 24 '11 at 20:43
  • @Kanishk: quoting the standard is an ongoing process, The more you refer to it, the more its style and jargon start to make sense. Then you can get away from relying on examples from tutorials, half-remembered rules, and gut instinct :-) – Steve Jessop Feb 24 '11 at 20:45
2

Your compiler initialized the value of x to be 0.

It's a global variable which is visible from within main()

John Weldon
  • 39,849
  • 11
  • 94
  • 127
1

x is a global variable, it has space allocated for it when the program starts and is initialized to 0 (generally, however you should have an explicit initializer).

The 'static' keyword has two different meanings.

1)

static int x;

int main() { }

This limits the scope of x to the single file. Although it is still a global variable, the linker will not be able to connect references to x from other files.

2)

int main() {
   static int x;
}

This effectively turns x into a global variable. Although the scope is still within the main function, space is allocated for it globally, and it's value will be retained between calls to main().

0

This feels like a homework question but I'll bite anyhow.

To use the x you have defined here in a class or function from another file, you would use

extern int x;

above your usage of the x variable (like in the header) then you can use x just like you would in main(). extern tells the compiler that you are using a variable that is defined/instantiated elsewhere.

If you want it to exist before the main is run, then you use static which is handled prior to main() running. In other words it loads the memory space with variables prior to kicking off any processing (in main.)

As to why it is 0 on startup, that is likely just your compiler giving it a base value. Not all compilers do this, unless I am mistaken, many will just give you whatever was in the memory space allocated to x which could be anything. In other words they give you the memory complete with whatever data (or partial data) was in it beforehand.

Justin
  • 11
  • 1
  • 3
    How is this homework? I am not asking you to write code for me. I am asking something which I have tried. Homework questions are not like this. – Kanishk Feb 24 '11 at 20:42