Reputation: 6295
I was disappointed to learn recently that C does not allow assignment of variables during static variable initialization, unlike C++. E.g. the following code compiles as C++...
#include <stdio.h>
int foo()
{
return 1;
}
static int g_i = foo();
int main( int argc, char* argv[] )
{
printf( "%d\n", g_i );
return 0;
}
...but issues the following error with a C compiler:
>cc -g main.c
main.c:8:1: error: initializer element is not constant
static int g_i = foo();
^
I thought I could be clever by using the comma operator a-la:
static int g_i = ( foo(), 1 );
...but the compiler seemed unimpressed with my attempted cleverness, and output effectively the same error:
>cc -c main.c
main.c:8:1: error: initializer element is not constant
static int g_i = ( foo(), 1 );
^
:(
Q: Why does use of the comma operator not work? I may be unaware of some subtlety, but my understanding led me to think it should have worked: the C
compiler is demanding g_i
be initialzed to a compiletime constant; supposedly the comma operator would have offered me evaluation of the code left of the comma, but assignment of the code right of the comma, which is a compiletime constant.
Q: Are there any hacks - I don't care how dirty - that would allow assignment to g_i
the return value of foo()
to g_i
?
This is a simplified representation of a C
program where I really just want to call a function before main()
- I don't care about the return value, but it's a more complicated problem to call a void
function before main()
, which I would rather sidestep altogether by using an int
function whose value is assigned to a throwaway static int
variable.
Upvotes: 1
Views: 257
Reputation: 320777
C does not support dynamic initialization. For this reason, static objects are required to be initialized with constant expressions. Constant expressions are not allowed to involve any run-time computations, even if these computations do not affect the final value of the expression. Your expression with comma operator is not a constant expression.
(Moreover, comma operator is prohibited in C constant expressions even if you don't call any functions from them. E.g. even something as trivial as (1, 2, 3)
is not a constant expression either.)
All static objects in C have to be initialized at compile time, at least conceptually. The word "conceptually" in this case refers to the fact that, say, address constant expressions may actually be evaluated much later, even at load time. But the point is that once your program starts running any user-level code, all static objects have to have already known pre-evaluated values, as if they were initialized at compile time. For this reason C (as opposed to C++) does not have/does not need the concept of initialization order for static objects and cannot possibly suffer from SIOF.
So, there's no way around this restriction in standard C. You will not be able to initialize a static object with something that requires (or in any way involves) running code at run-time. Your implementation might provide implementation-specific features that might be able to do something like that, but this is way outside the realm of C language itself.
Upvotes: 8