Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why's initializing a global variable with return value of a function failing at declaration,but works fine at file scope?

An 80k reputation contributor R.. told me on SO that we can't initialize global variables with the return value of a function as that's not considered a constant,and global variables must be initialized with a constant.And true to his words,I get the following error for this program as expected-- initializer element is not a constant.Here is the program:

#include<stdio.h>
int foo();
int gvar=foo();  //ERROR

int main()
{
printf("%d",gvar);
}

int foo()
{
 return 8;
}

But in this context,I just don't understand why the followed altered version of the above program shows no error at all and works fine.In this second program,I am initializing the same global variable with the return value of the same function foo().Can you tell me what is the rigorous technical reason for this variation in results?Why is initializing the global variable with the return value of a function at it's declaration causing error but the same initialization with the same return value works fine when done from within a function?

#include<stdio.h>
int foo();
int gvar;

int main()
{
gvar=foo();
printf("%d",gvar);
}

int foo()
{
return 8;
}

Output 8

like image 554
Rüppell's Vulture Avatar asked May 03 '13 08:05

Rüppell's Vulture


2 Answers

The reason behind it is that in order to determine a value produced by a function one needs to execute code, and that there is no code execution done in C when initializing static and global variables.

Compiler and linker work together to prepare a byte image of the global memory segment: the compiler provides the values, and the linker performs their final layout. At runtime, the image of the segment is loaded in memory as is, without further modifications. This happens before any code gets executed, so no function calls can be made.

Note that this does not mean that it is not possible for some technical reason, only that C designers decided against doing it. For example, C++ compiler generates a code segment that calls constructors of global objects, which gets executed before the control is passed to main().

like image 53
Sergey Kalinichenko Avatar answered Sep 29 '22 22:09

Sergey Kalinichenko


The second version doesn't have an initializer for gvar. gvar is declared and defined at global scope without an initializer. It has static storage duration, so it is initialized with zero.

The assignment in main is just that: an assignment, not an initialization.

like image 45
Mat Avatar answered Sep 30 '22 00:09

Mat