0
votes

I have written below code (Just for understanding purpose only). Outside the main, int b; means tentative definition. Inside main int b=16 is a local variable. Inside the function variable b has internal linkage (file scope). The output is 16 and 0. I read that memory is allocated for tentatively defined variables only when they are initialized. So here my question is inside function, printf prints the value of b and does the memory gets allocated when printf called? In case it is so, can I say that memory is allocated to a tentatively defined variables when they are first accessed (whether initialized or accessed)? Or am I wrong?

int b;
int b;
void f1(int a1);
int main ()
{
    int b=16;
    printf("b=%d\n",b);
    f1(5);
    return 0;
}

void f1(int a1)
{
    printf("b = %d\n",b);
}

Edited: Adding more clarity: I am aware that variable inside the function is different from that in main. Also aware that local variable is in stack. My question here is with respect to tentative definition. int b was declared twice and it is accepted in C because it is tentative definition. In case it is actual definition, then multiple definitions are not allowed and hence this is not accepted. There are several questions on tentative definition (About Tentative definition). According to one of them "C has a special "tentative definition" rule which allows multiple definitions for the same variable so long as they all match and at most one has an initializer. The C compiler, behind the scenes, combines all of the tentative definitions into a single definition." So to rephrase my question:

Does memory gets allocated if variable is just tentatively defined, but not used? (assuming that compiler does not optimize the code). It looks like at the end of translation unit, memory gets allocated as per the question linked above. Or whether memory is allocated only when it is used for the fist time (in this case in printf statement)?

2
Is int b; int b; allowed? :Ocadaniluk
"A tentative definition becomes a full definition if the end of the translation unit is reached and no definition has appeared with an initializer for the identifier". So the last tentative definition is becoming an actual one with global scope and zero initialized.Eugene Sh.
@cad: As they are identical: yes. Not sure if this is true if one is e.g. typedef int it; it b;, had to lookup in the standard, but I'd avoid this like hell anyway.too honest for this site
I think @Eugene Sh answered my question. If it is an answer, I would have accepted this as answer!Jon Wheelock
Also Tentative definition applies to only single file or even across multiple files?Jon Wheelock

2 Answers

0
votes

These are two different variables.

For the global int b; the memory is allocated when the program is first loaded into memory. It is allocated in the program's global memory, and can be easily accessed from any point in the program.

For the main()'s local int b=16; is allocated on the stack, in the main() function frame. It can only be directly accessed from that function.. Anything else requires either that main() pass the variables address or some complex pointer arithmetic on the stack.

The local b hides the global b because they have the same name, so you cannot use the global one from this function (some languages allow this, C doesn't), but that is it. They are different variables, and your program's binary (i.e. the actual instructions executed) would not change if you changed the name.

0
votes

See this answer that explains why int b; is zero initialized.

Does gcc automatically initialize static variables to zero?

The int b; in main is on the stack and set to 16. In your function f1 the only b symbol that's in scope is the one declared at file scope and it's zero initialized because that's what the standard says it should be.