FILE * .. = stdout:错误初始化器元素不是恒定的 [英] FILE * ..=stdout : Error initializer element is not constant

查看:126
本文介绍了FILE * .. = stdout:错误初始化器元素不是恒定的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的C代码如下:

[Linux:/si/usr/hrl]vi test.c    

#include <stdio.h>

FILE * hw = stdout;

int main(void)
{
        return 0;
}

当我在SUSE上编译时,它会产生如下错误:

When I compile on SUSE , it make the error like that:

[Linux:/si/usr/hrl]cc test.c -o test
test.c:3: error: initializer element is not constant

我查找了头文件 stdio.h ,发现 stdout 似乎已定义为常量.那么为什么会产生错误呢?顺便说一句,我在AIX上编译了相同的代码,成功的结果.

I have a look for the header file stdio.h and find that stdout seems to have be defined as a constant. So why the error produce?By the way, I compile the same code on AIX ,it results of success.

推荐答案

该标准不需要 stdin stdout stderr 常数.

The standard does not require stdin, stdout and stderr to be constants.

用于C99的n1256草案在7.19.1输入/输出< stdio.h>

The draft n1256 for C99 says in 7.19.1 Input/output <stdio.h>

标头声明...
...
TMP_MAX
它扩展为整数常量表达式 ...

stderr标准输入标准输出
这是类型为指向文件的指针"的表达式 ...

stderr stdin stdout
which are expressions of type ‘‘pointer to FILE’’ ...

(强调我的)

明确指出其他一些值是常量,而 stdin stdout stderr

It is explicitely stated that some other values are constant, whereas nothing is said for stdin, stdout and stderr

因此,您必须将初始化放在main中:

So you must put initialization in main:

#include <stdio.h>

FILE * hw;

int main(void)
{
        hw = stdout;
        ...
        return 0;
}

在AIX标准库中, stdout 恰好是一个常量,但这只是实现细节,您不能依赖它,因为它可能会在任何较新的版本中出现.

In AIX standard library, stdout happens to be a constant, but it is just an implementation detail and you cannot rely on that, as it could break in any newer version.

但是您不应该依赖 stdout 作为变量(甚至也不是左值),因为它也是GCC库中的实现细节.

But you should not rely either on stdout being a variable (nor even a lvalue), because it is also an implementation detail in GCC library.

如果您无法更改大部分代码,而只需要GCC hack使其可编译,则可以尝试使用gcc constructor属性扩展名.

If you cannot change much of your code, and just need a GCC hack to make it compilable, you could try to use the gcc constructor attribute extension.

gcc文档中提取

6.31声明函数的属性

6.31 Declaring Attributes of Functions

在GNU C中,您声明了有关程序中所调用函数的某些内容,这有助于编译器优化函数调用并更仔细地检查代码.

In GNU C, you declare certain things about functions called in your program which help the compiler optimize function calls and check your code more carefully.

关键字 __ attribute __ 允许您在进行声明时指定特殊属性.此关键字后跟双括号内的属性说明.当前为所有目标上的函数定义了以下属性:...,构造函数,...
...
构造函数属性使函数在执行进入main()之前自动被调用.

The keyword __attribute__ allows you to specify special attributes when making a declaration. This keyword is followed by an attribute specification inside double parentheses. The following attributes are currently defined for functions on all targets: ... ,constructor, ...
...
The constructor attribute causes the function to be called automatically before execution enters main () ...

因此您可以使用:

#include <stdio.h>

FILE * hw;

void initHw(void) __attribute__((constructor)) {
    hw = stdout;
}

int main(void)
{
        return 0;
}

但是当心:这是一个gcc扩展名,表示您的代码不是正确的C.

But BEWARE: it is a gcc extension, meaning that your code is not correct C.

这篇关于FILE * .. = stdout:错误初始化器元素不是恒定的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆