Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error initializer element is not constant

Tags:

c

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:

initializer element is not constant
like image 772
Alexandre Avatar asked Oct 01 '11 23:10

Alexandre


3 Answers

try doing it in main for example:

static FILE *debugOut;
static FILE *infoOut;

main(){
    debugOut = stderr;
    infoOut = stdout;


}
like image 103
fazo Avatar answered Oct 19 '22 12:10

fazo


The ANSI C standard does not demand that stderr/stdout have to be constant expressions.

Thus, depending on the used standard C library code like this

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.

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:

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.

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

like image 36
maxschlepzig Avatar answered Oct 19 '22 12:10

maxschlepzig


From the C99 standard:

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.

Hence,

static FILE *debugOut = stderr;
static FILE *infoOut = stdout;

is not legal code if compiler does not think stderr and stdout are constant expressions.

This is what the standard has to say about stderr and stdout.

7.19 Input/output <stdio.h>

7.19.1 Introduction

...

   stderr
   stdin
   stdout

which are expressions of type ‘‘pointer to FILE’’ that point to the FILE objects associated, respectively, with the standard error, input, and output streams.

Solution

The standard compliant way to deal with this is to initialize the variables to NULL and set their values in main.

static FILE *debugOut = NULL;
static FILE *infoOut  = NULL;

int main()
{
  debugOut = stderr;
  infoOut  = stdout;

  ...
like image 28
R Sahu Avatar answered Oct 19 '22 12:10

R Sahu