我收到以下代码的以下错误,“1506-221 (S) Initializer must be a valid constant expression”
FILE *fp[] = {stdout, dump_f};
这是可以接受的吗?实现这一目标的正确方法是什么?
该错误表明在您的系统上,该stdout
变量实际上是一个#defined
扩展为函数调用的宏。
实际上,正如其他人所建议的那样,它可能只是stdout
一个外部声明的变量,其值在编译时未知,因此不能在静态初始化程序中提供。
无论如何,解决方案应该是相同的 - 我会尝试类似的东西:
FILE *fp[2];
void init_fp()
{
fp[0] = stdout;
fp[1] = dump_f;
}
如果那是全局的,那么 C 不支持使用函数调用对其进行初始化。如果stdout
是函数调用的宏(如最初建议的那样),那么您将无法使用它来初始化全局。
很可能,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;
经典地,大多数 Unix 系统曾经定义stdout
为类似的东西(&_iob[1])
,它被简化为一个有效的常量表达式;例如,Solaris 仍然如此。
几年前,现在,GNU C 库将其定义更改为stdout
非常量,因此用于将FILE *
变量初始化为任何标准文件指针的旧代码停止编译。这是C标准认可的,所以抱怨没有任何美德。您只需要接受您无法初始化指向标准 I/O 通道之一的静态文件指针并重新编码以解决该问题。(但这仍然是一个麻烦。)