My C code was as following:
[Linux:/si/usr/hrl]vi test.c
#include <stdio.h>
FILE * hw = stdout;
int main(void)
{
return 0;
}
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
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.
The standard does not require stdin
, stdout
and stderr
to be constants.
The draft n1256 for C99 says in 7.19.1 Input/output <stdio.h>
The header declares ...
...
TMP_MAX
which expands to an integer constant expression ...stderr stdin stdout
which are expressions of type ‘‘pointer to FILE’’ ...
(emphasize mine)
It is explicitely stated that some other values are constant, whereas nothing is said for stdin
, stdout
and stderr
So you must put initialization in main:
#include <stdio.h>
FILE * hw;
int main(void)
{
hw = stdout;
...
return 0;
}
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.
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.
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.
Extract from gcc documentation
6.31 Declaring Attributes of Functions
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.
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 () ...
So you could use:
#include <stdio.h>
FILE * hw;
void initHw(void) __attribute__((constructor)) {
hw = stdout;
}
int main(void)
{
return 0;
}
But BEWARE: it is a gcc extension, meaning that your code is not correct C.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With