简体   繁体   中英

static variable initialization in C

I was disappointed to learn recently that C does not allow assignment of variables during static variable initialization, unlike C++. Eg 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.

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. Eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM