Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FILE * ..=stdout : Error initializer element is not constant

Tags:

c

linux

suse

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.

like image 203
hrl Avatar asked Feb 24 '16 07:02

hrl


1 Answers

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.

like image 70
Serge Ballesta Avatar answered Nov 02 '22 07:11

Serge Ballesta