我的C代码如下:
[Linux:/si/usr/hrl]vi test.c
#include <stdio.h>
FILE * hw = stdout;
int main(void)
{
return 0;
}
当我在SUSE上编译时,会出现如下错误:
[Linux:/si/usr/hrl]cc test.c -o test
test.c:3: error: initializer element is not constant
我查看了头文件stdio.h
,发现stdout
似乎已被定义为常量。那么为什么错误会产生?顺便说一句,我在AIX上编译相同的代码,这是成功的结果。
答案 0 :(得分:4)
该标准不要求stdin
,stdout
和stderr
为常量。
C99的n1256草案在7.19.1中输入/输出&lt; stdio.h&gt;
标题声明......
...
TMP_MAX
扩展为整数常量表达式 ...stderr的 标准输入 标准输出
其中表达式类型''指向FILE的指针''...
(强调我的)
明确指出,其他一些值是不变的,而stdin
,stdout
和stderr
所以你必须在main中放置初始化:
#include <stdio.h>
FILE * hw;
int main(void)
{
hw = stdout;
...
return 0;
}
在AIX标准库中,stdout
恰好是一个常量,但它只是一个实现细节,你不能依赖它,因为它可能会破坏任何更新的版本。
但你不应该依赖stdout
作为变量(甚至是左值),因为它也是GCC库中的实现细节。
如果您无法更改大部分代码,只需要GCC hack来使其可编译,您可以尝试使用gcc 构造函数属性扩展名。
6.31声明函数的属性
在GNU C中,您声明了程序中调用的某些函数,这些函数可以帮助编译器优化函数调用并更仔细地检查代码。
关键字
之前自动调用该函数__attribute__
允许您在进行声明时指定特殊属性。此关键字后面是双括号内的属性规范。目前为所有目标上的函数定义了以下属性:...,构造函数,...
...
构造函数属性导致在执行main()...
所以你可以使用:
#include <stdio.h>
FILE * hw;
void initHw(void) __attribute__((constructor)) {
hw = stdout;
}
int main(void)
{
return 0;
}
但请注意:它是gcc扩展名,意味着您的代码不正确C。