I am having trouble with my code, and I can not solve ....
我的代码有问题,我无法解决....
the code snippet where the error is reported:
报告错误的代码段:
static FILE *debugOut = stderr;
static FILE *infoOut = stdout;
The error that the gcc return is:
gcc返回的错误是:
initializer element is not constant
3 个解决方案
#1
7
The ANSI C standard does not demand that stderr
/stdout
have to be constant expressions.
ANSI C标准不要求stderr / stdout必须是常量表达式。
Thus, depending on the used standard C library code like this
因此,取决于使用的标准C库代码
static FILE *debugOut = stderr;
compiles or yields the error message you have asked about.
编译或产生您询问的错误消息。
For example, the GNU C library defines stderr
/stdout
/stdin
as non-constant expressions.
例如,GNU C库将stderr / stdout / stdin定义为非常量表达式。
You have basically two options to deal with this situation, i.e. to make such code portable.
您基本上有两种选择来处理这种情况,即使这些代码可移植。
Initialization from main
static FILE *debugOut = NULL;
static FILE *infoOut = NULL;
int main(int argc, char **argv)
{
debugOut = stderr;
infoOut = stdout;
// [..]
return 0;
}
Initialization from a constructor function
On many platforms you can declare a function as constructor, meaning that it is called on startup before main()
is called. For example when using GCC you can implement it like this:
在许多平台上,您可以将函数声明为构造函数,这意味着它在调用main()之前在启动时调用。例如,当使用GCC时,您可以像这样实现它:
static FILE *debugOut = NULL;
static FILE *infoOut = NULL;
static void init_streams(void) __attribute__((constructor));
static void init_streams(void)
{
debugOut = stderr;
infoOut = stdout;
}
This constructor attribute syntax is not standardized, but since GCC is very widespread and other compilers strive for GCC compatibility this is actually quite portable.
这种构造函数属性语法不是标准化的,但由于GCC非常普遍,而其他编译器也在努力实现GCC兼容性,因此实际上它非常便于携带。
In case you need to make this portable to other compilers that does not have a similar declaration feature you can guard this code with macros like __GNU_LIBRARY__
and/or __GNUC__
.
如果您需要将其移植到没有类似声明功能的其他编译器,您可以使用__GNU_LIBRARY__和/或__GNUC__等宏来保护此代码。
#2
8
try doing it in main for example:
尝试在主要做例如:
static FILE *debugOut;
static FILE *infoOut;
main(){
debugOut = stderr;
infoOut = stdout;
}
#3
3
From the C99 standard:
从C99标准:
6.7.8 Initialization
Constraints
4 All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
4具有静态存储持续时间的对象的初始值设定项中的所有表达式应为常量表达式或字符串文字。
Hence,
static FILE *debugOut = stderr;
static FILE *infoOut = stdout;
is not legal code if compiler does not think stderr
and stdout
are constant expressions.
如果编译器认为stderr和stdout不是常量表达式,则不是合法代码。
This is what the standard has to say about stderr
and stdout
.
这是标准对stderr和stdout的看法。
7.19 Input/output
<stdio.h>
7.19输入/输出
7.19.1 Introduction
...
stderr stdin stdout
which are expressions of type ‘‘pointer to
FILE
’’ that point to theFILE
objects associated, respectively, with the standard error, input, and output streams.它是“指向FILE的指针”类型的表达式,它们分别指向与标准错误,输入和输出流相关联的FILE对象。
Solution
The standard compliant way to deal with this is to initialize the variables to NULL
and set their values in main
.
处理此问题的标准兼容方法是将变量初始化为NULL并在main中设置它们的值。
static FILE *debugOut = NULL;
static FILE *infoOut = NULL;
int main()
{
debugOut = stderr;
infoOut = stdout;
...
#1
7
The ANSI C standard does not demand that stderr
/stdout
have to be constant expressions.
ANSI C标准不要求stderr / stdout必须是常量表达式。
Thus, depending on the used standard C library code like this
因此,取决于使用的标准C库代码
static FILE *debugOut = stderr;
compiles or yields the error message you have asked about.
编译或产生您询问的错误消息。
For example, the GNU C library defines stderr
/stdout
/stdin
as non-constant expressions.
例如,GNU C库将stderr / stdout / stdin定义为非常量表达式。
You have basically two options to deal with this situation, i.e. to make such code portable.
您基本上有两种选择来处理这种情况,即使这些代码可移植。
Initialization from main
static FILE *debugOut = NULL;
static FILE *infoOut = NULL;
int main(int argc, char **argv)
{
debugOut = stderr;
infoOut = stdout;
// [..]
return 0;
}
Initialization from a constructor function
On many platforms you can declare a function as constructor, meaning that it is called on startup before main()
is called. For example when using GCC you can implement it like this:
在许多平台上,您可以将函数声明为构造函数,这意味着它在调用main()之前在启动时调用。例如,当使用GCC时,您可以像这样实现它:
static FILE *debugOut = NULL;
static FILE *infoOut = NULL;
static void init_streams(void) __attribute__((constructor));
static void init_streams(void)
{
debugOut = stderr;
infoOut = stdout;
}
This constructor attribute syntax is not standardized, but since GCC is very widespread and other compilers strive for GCC compatibility this is actually quite portable.
这种构造函数属性语法不是标准化的,但由于GCC非常普遍,而其他编译器也在努力实现GCC兼容性,因此实际上它非常便于携带。
In case you need to make this portable to other compilers that does not have a similar declaration feature you can guard this code with macros like __GNU_LIBRARY__
and/or __GNUC__
.
如果您需要将其移植到没有类似声明功能的其他编译器,您可以使用__GNU_LIBRARY__和/或__GNUC__等宏来保护此代码。
#2
8
try doing it in main for example:
尝试在主要做例如:
static FILE *debugOut;
static FILE *infoOut;
main(){
debugOut = stderr;
infoOut = stdout;
}
#3
3
From the C99 standard:
从C99标准:
6.7.8 Initialization
Constraints
4 All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
4具有静态存储持续时间的对象的初始值设定项中的所有表达式应为常量表达式或字符串文字。
Hence,
static FILE *debugOut = stderr;
static FILE *infoOut = stdout;
is not legal code if compiler does not think stderr
and stdout
are constant expressions.
如果编译器认为stderr和stdout不是常量表达式,则不是合法代码。
This is what the standard has to say about stderr
and stdout
.
这是标准对stderr和stdout的看法。
7.19 Input/output
<stdio.h>
7.19输入/输出
7.19.1 Introduction
...
stderr stdin stdout
which are expressions of type ‘‘pointer to
FILE
’’ that point to theFILE
objects associated, respectively, with the standard error, input, and output streams.它是“指向FILE的指针”类型的表达式,它们分别指向与标准错误,输入和输出流相关联的FILE对象。
Solution
The standard compliant way to deal with this is to initialize the variables to NULL
and set their values in main
.
处理此问题的标准兼容方法是将变量初始化为NULL并在main中设置它们的值。
static FILE *debugOut = NULL;
static FILE *infoOut = NULL;
int main()
{
debugOut = stderr;
infoOut = stdout;
...