Reputation: 11
int a = 5;
int b = a; //error, a is not a constant expression
int main(void)
{
static int c = a; //error, a is not a constant expression
int d = a; //okay, a don't have to be a constant expression
return 0;
}
I don't understand what happens when a C compiler handles those variable declarations.
Why was C designed to be unable to handle int b = a
?
Upvotes: 0
Views: 742
Reputation: 222272
The specific rule that applies here is C 2018 6.7.9 4:
All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.
The primary reason for this arises from the way that C is typically implemented, with a compiler generating object modules (which are later linked into executables and run). In such a C implementation, initializing an object with static storage duration requires the compiler to know the initial value, whereas initializing an object with automatic storage duration does not require the compiler to know the initial value.
This is because, to initialize an object with static storage duration, the compiler must put the initial value into the object module being generated. To initialize an object with automatic storage duration, the compiler merely needs to generate instructions to get or calculate the initial value and store it in the object.
When int a = 5;
and int b = a;
appear outside of any function, a
and b
have static storage duration. At this point, the compiler could, in theory, see that a
was initialized with the value five, so it has that value when used in int b = a;
. However, there are some issues with this:
b
uses only objects that have been initialized earlier in the same translation unit. Extending the language to require the compiler to support this would require more complicated rules.Another possibility would be that, to make initializations like int b = a;
work, the compiler does it by generating instructions to be executed when the program starts, possibly immediately before main
is called. This adds complications, including:
int b = a;
appears in a translation unit other than the one containing main
, how is the code necessary to initialize b
inserted in main
or in the program start-up code?These problems could be solved, in theory, but C is intended to be a “simple” language.
Upvotes: 2
Reputation: 213286
This happens because variables declared outside any function (at file scope) or variables declared as static
both get static storage duration. Such variables are initialized before main() is even called. And that early on in the execution, values that aren't pure constant expressions might not yet be available.
RAM-based hosted systems like PC might even initialize such variables in one go, at the point where the executable is copied from the hard-drive to RAM, which gives very fast initialization. Which wouldn't be possible if you did something like static x = func();
because then you definitely have to execute func()
before setting x
.
There's also the issue of static initialisation order. Suppose a
and b
were declared in separate files, which should get initialized first, a
or b
?
C++ unlike C has decided to allow more complex forms of initialization and as a result, C++ has very complex initialization rules. And also it is a very common C++ bug to write code depending on the order of static initialization. There are valid arguments for/against both the C and the C++ way.
Upvotes: 1