C中的静态变量初始化

Sto*_*row 1 c c++ static

最近我很失望地了解到C不允许在静态变量初始化期间分配变量,这与C++不同.例如,以下代码编译为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;
}
Run Code Online (Sandbox Code Playgroud)

...但是使用C编译器发出以下错误:

>cc -g main.c
main.c:8:1: error: initializer element is not constant
 static int g_i = foo();
 ^
Run Code Online (Sandbox Code Playgroud)

我以为我可以通过使用逗号运算符a-la来聪明:

static int g_i = ( foo(), 1 );
Run Code Online (Sandbox Code Playgroud)

...但编译器似乎对我的聪明才智并不感兴趣,并且有效地输出了相同的错误:

>cc -c main.c
main.c:8:1: error: initializer element is not constant
 static int g_i = ( foo(), 1 );
 ^ 
Run Code Online (Sandbox Code Playgroud)

:(

:为什么使用逗号运算符不起作用?我可能没有意识到一些微妙之处,但我的理解让我觉得它应该有效:C编译器要求g_i初始化为编译时常量; 据说逗号运算符会给我评估逗号左边的代码,但是为逗号分配代码,这是一个编译时常量.

Q:是否有任何黑客-我不在乎有多脏-这将允许分配g_i的返回值foo()g_i

这是一个C程序的简化表示,我真的只想在之前调用一个函数main()- 我不关心返回值,但是void之前调用函数是一个更复杂的问题main(),我宁愿通过使用一个函数完全回避它.int将其值赋值给一次性static int变量的函数.

AnT*_*AnT 8

C不支持动态初始化.因此,需要使用常量表达式初始化静态对象.不允许常量表达式涉及任何运行时计算,即使这些计算不影响表达式的最终值.使用逗号运算符的表达式不是常量表达式.

(此外,即使你不从它们调用任何函数,也禁止在C常量表达式中使用逗号运算符.例如,即使是一些微不足道的东西(1, 2, 3)也不是常量表达式.)

C语言中的所有静态对象必须在编译时初始化,至少在概念上是这样.在这种情况下,"概念上"一词指的是,地址常量表达式实际上可以在很晚的时候进行评估,即使在加载时也是如此.但问题是,一旦程序开始运行任何用户级代码,所有静态对象都必须已经知道预先评估的值,就像它们在编译时被初始化一样.由于这个原因,C(与C++相对)没有/不需要静态对象的初始化顺序的概念,并且不可能遭受SIOF.

因此,在标准C中无法解决此限制.您将无法使用在运行时运行代码(或以任何方式涉及)运行代码的方式初始化静态对象.您的实现可能提供特定于实现的功能,可能能够执行类似的操作,但这超出了C语言本身的范畴.