C 错误初始值设定项元素不是常量

C 错误初始值设定项元素不是常量,c,C,我的代码有问题,我无法解决 报告错误的代码段: static FILE *debugOut = stderr; static FILE *infoOut = stdout; gcc返回的错误为: initializer element is not constant 尝试在main中执行此操作,例如: static FILE *debugOut; static FILE *infoOut; main(){ debugOut = stderr; infoOut = stdou

我的代码有问题,我无法解决

报告错误的代码段:

static FILE *debugOut = stderr;
static FILE *infoOut = stdout;
gcc返回的错误为:

initializer element is not constant

尝试在main中执行此操作,例如:

static FILE *debugOut;
static FILE *infoOut;

main(){
    debugOut = stderr;
    infoOut = stdout;


}

ANSI C标准不要求
stderr
/
stdout
必须是常量表达式

因此,根据使用的标准C库代码,如下所示

static FILE *debugOut = stderr;
编译或生成您询问的错误消息

例如,
stderr
/
stdout
/
stdin
作为非常量表达式

处理这种情况基本上有两种选择,即使这种代码可移植

从主服务器初始化 从构造函数初始化 在许多平台上,可以将函数声明为构造函数,这意味着在调用
main()。例如,在使用时,您可以这样实现:

static FILE *debugOut = NULL;
static FILE *infoOut  = NULL;

static void init_streams(void) __attribute__((constructor)); 
static void init_streams(void)
{
  debugOut = stderr;
  infoOut  = stdout;
}
这种语法并没有标准化,但由于GCC非常广泛,而且其他编译器都在努力实现GCC兼容性,因此它实际上是非常可移植的

如果您需要将此代码移植到其他没有类似声明功能的编译器,您可以使用C99标准中的宏来保护此代码,如
\uuuuu GNU\u LIBRARY\uuuuu
和/或
\uuuuuuu GNU\uuu

6.7.8初始化

约束

4具有静态存储持续时间的对象的初始值设定项中的所有表达式应为常量表达式或字符串文字

因此,

static FILE *debugOut = stderr;
static FILE *infoOut = stdout;
如果编译器不认为
stderr
stdout
是常量表达式,则此代码不合法

这就是标准对
stderr
stdout
的定义

7.19输入/输出

7.19.1导言

   stderr
   stdin
   stdout
它们是“指向
文件的指针”
”类型的表达式,分别指向与标准错误、输入和输出流关联的
文件
对象

解决方案

处理此问题的标准兼容方法是将变量初始化为
NULL
,并在
main
中设置它们的值

static FILE *debugOut = NULL;
static FILE *infoOut  = NULL;

int main()
{
  debugOut = stderr;
  infoOut  = stdout;

  ...

您需要发布更多的代码,因为这还不够,gcc报告的也是这些吗?还可以尝试在函数中分配它们(我想您现在是作为全局变量来做的?)您正在初始化一个静态变量,这意味着编译器需要知道编译时的值是什么。您试图分配一个编译器在编译时不知道但在运行时知道的值-这就是它导致错误的原因。它不是重复的-它比链接的问题更具体-一个好的答案将详细说明为什么stderr/stdout在某些c库中是常量表达式-但不是全部-以及c标准并不要求它们是常量表达式。然后添加上述代码的一些可移植变体。@AndreasL。我最初的回答是指出问题所在。我添加了一个解决方案。谢谢。我正在迁移旧代码,并且没有main方法,所以我在使用“file”的每个方法中都进行检查(如果(file==NULL){file=stdout;})。“文件”可能是在其他地方设置的。。。
static FILE *debugOut = NULL;
static FILE *infoOut  = NULL;

int main()
{
  debugOut = stderr;
  infoOut  = stdout;

  ...