我为以下代码收到以下错误, “1506-221(S)初始值设定项必须是有效的常量表达式”
FILE *fp[] = {stdout, dump_f};
这是可以接受的吗?实现这个目标的正确方法是什么?
答案 0 :(得分:4)
该错误表明,在您的系统上,stdout
变量实际上是一个#defined
宏,它会扩展为函数调用。
实际上,正如其他人所建议的那样,可能只是stdout
是一个外部声明的变量,其值在编译时是未知的,因此无法在静态初始化器中提供。
无论哪个,解决方案应该是相同的 - 我会尝试类似的东西:
FILE *fp[2];
void init_fp()
{
fp[0] = stdout;
fp[1] = dump_f;
}
答案 1 :(得分:2)
如果是全局的,则C不支持使用函数调用初始化它。如果stdout
是函数调用的宏(如最初建议的那样),那么您将无法使用它来初始化全局。
答案 2 :(得分:2)
很可能stdout
和/或dump_f
是宏或(更有可能是问题)外部全局变量。
如果我有这段代码:
// external.c
int hello = 1234;
// external.h
extern int hello;
// main.c
#include "external.h"
int world = hello; // error!
您会在指定的行收到错误,因为hello
的值未知。
stdout
和dump_f
很可能被声明为extern
全局变量,如下所示:
extern FILE *stdout, *stdin, *stderr, *dump_f;
答案 3 :(得分:2)
传统上,大多数Unix系统用于将stdout
定义为类似(&_iob[1])
的东西,它缩减为有效的常量表达式;例如,Solaris仍然可以。
几年前,现在,GNU C库将stdout
的定义更改为不是常量的东西,所以旧代码用于将FILE *
变量初始化为任何标准文件指针停止编译。这是由C标准认可的,所以抱怨没有任何优点。您只需接受不能将静态文件指针初始化为其中一个标准I / O通道并重新编码以解决问题。 (但它 仍然是一种麻烦。)