文件问题

时间:2009-01-15 23:50:00

标签: c file stdout stdio

我为以下代码收到以下错误, “1506-221(S)初始值设定项必须是有效的常量表达式”

FILE          *fp[] = {stdout, dump_f};

这是可以接受的吗?实现这个目标的正确方法是什么?

4 个答案:

答案 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的值未知。

stdoutdump_f很可能被声明为extern全局变量,如下所示:

extern FILE *stdout, *stdin, *stderr, *dump_f;

答案 3 :(得分:2)

传统上,大多数Unix系统用于将stdout定义为类似(&_iob[1])的东西,它缩减为有效的常量表达式;例如,Solaris仍然可以。

几年前,现在,GNU C库将stdout的定义更改为不是常量的东西,所以旧代码用于将FILE *变量初始化为任何标准文件指针停止编译。这是由C标准认可的,所以抱怨没有任何优点。您只需接受不能将静态文件指针初始化为其中一个标准I / O通道并重新编码以解决问题。 (但它 仍然是一种麻烦。)