FILE * .. = stdout: the error initialization element is not a constant

My C code was as follows:

[Linux:/si/usr/hrl]vi test.c #include <stdio.h> FILE * hw = stdout; int main(void) { return 0; } 

When I compile on SUSE, it makes the following error:

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

I look at the stdio.h header file and find that stdout appears as a constant. So why is the error occurring? By the way, I am compiling the same code on AIX, this is the result of success.

+6
source share
1 answer

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

Draft n1256 for C99 says on 7.19.1. Login / Logout <stdio.h>

The headline announces ...
...
TMP_MAX
which expands to the whole expression of a constant ...

STDERR STDIN standard output
which are '' type pointer expressions for FILE ...

(underline mine)

It is explicitly stated that some other values ​​are constant, whereas for stdin , stdout and stderr

nothing is said

So you should enable initialization in main:

 #include <stdio.h> FILE * hw; int main(void) { hw = stdout; ... return 0; } 

In the AIX standard library, stdout is constant, but this is just an implementation detail, and you cannot rely on it because it can break in any newer version.

But you should not rely on stdout as a variable (and even lvalue), since it is also a detail of the implementation in the GCC library.


If you can't change most of your code and just need to hack GCC to make it compiled, you can try using the gcc constructor attribute extension.

Extract from gcc documentation

6.31 Declaring function attributes

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 thoroughly.

The __attribute__ keyword allows you to specify special attributes when creating an ad. This keyword is followed by an attribute specification inside double brackets. Currently, the following attributes are defined for functions of all purposes: ..., constructor , ...
...
The constructor attribute causes the function to be called automatically before execution starts main () ...

So you can use:

 #include <stdio.h> FILE * hw; void initHw(void) __attribute__((constructor)) { hw = stdout; } int main(void) { return 0; } 

But BEWARE : this is a gcc extension, which means your code is not correct C.

+4
source

All Articles