Problem with non-constant initializers

Zack Weinberg
Thu Sep 30 19:57:00 GMT 1999

Eric Scharff wrote:
> (Probably not a bug, but I can't find documentation or see why this doesn't
> work)
> #include <stdio.h>
> FILE *xout = stdout;
> int main(int argc, char *argv[]) {
>   fprintf(xout, "Hi there!\n");
> }
> ---
> gcc tst.c
> tst.c:3: initializer element is not constant

(a) This has *nothing* to do with gcc.  If you use the gcc-2.7.2
package that comes with redhat 6, you will see the exact same
behavior.  stdio.h, which defines stdout, is provided by the system C
library - for redhat 6, this is GNU libc.  You should have asked this
question on

(b) The C standard allows stdout to be either a constant or a
variable; likewise stderr and stdin.  The developers of GNU libc have
chosen to make stdout, stdin, and stderr variables.  This does break
code, but the implementation is cleaner and you can assign -to-
stdout, which is occasionally useful.

(c) One can make a decent case that stdout should be a constant, for
backward compatibility.  However, it cannot be changed now because
that would break _binary_ compatibility with already-compiled
programs.  This is to be avoided at all cost.

(d) There is a trivial workaround: move the global variable
initialization to the beginning of main().  If the variable is not in
scope at the beginning of main, you can either rearrange things so it
is, or add an initialization function which can see the variable, and
call that at the beginning of main.

(e) If you are having problems with code generated by old versions of
lex or yacc, may I suggest you try a recent version of flex, bison, or
byacc; all have been corrected to avoid this problem.


More information about the Gcc-bugs mailing list