static initializers in c

Started by
18 comments, last by SeanMiddleditch 10 years, 2 months ago

if i will wrote

int x = init();

in the static space this function init() will call even before the winmian

is called

I am writing c programs but compile it with c++ mode.. strange i never

used this kind of initialisers I was unaware of this.. (i think it may be handy though also maybe can bring some trouble, you must scan all the source to check what is called first etc)

1) I wonder is this a part of c standard as well or this is only c++ (and will not work in c)?

2) what with an order of calling this if i got more this than one (can i assume something on this order of calling or control order of it?)

3) is this generally encouraged way of writing in c (has it some downsides or pitfals?)

Advertisement


1) I wonder is this a part of c standard as well or this is only c++ (and will not work in c)?

C++ inherited it from C. It predates the standards and is a fundamental part of the language(s).

2) what with an order of calling this if i got more this than one (can i assume something on this order of calling or control order of it?)

Static initialization is always performed in lexical order within a translation unit. The order in which static initialization is performed between translation units is undefined (and will change from build to build).

3) is this generally encouraged way of writing in c (has it some downsides or pitfals?)

I would generally discourage the use of global (C) or namespace-level (C++) variables. No, really. They effectively preclude the use of threading or unit testing and they cause maintainers to swear like sailors at the free clinic.

Also, because sequencing between translation units is undefined and arbitrary, it often causes unexpected trouble.

Stephen M. Webb
Professional Free Software Developer


1) I wonder is this a part of c standard as well or this is only c++ (and will not work in c)?

C++ inherited it from C. It predates the standards and is a fundamental part of the language(s).

2) what with an order of calling this if i got more this than one (can i assume something on this order of calling or control order of it?)

Static initialization is always performed in lexical order within a translation unit. The order in which static initialization is performed between translation units is undefined (and will change from build to build).

3) is this generally encouraged way of writing in c (has it some downsides or pitfals?)

I would generally discourage the use of global (C) or namespace-level (C++) variables. No, really. They effectively preclude the use of threading or unit testing and they cause maintainers to swear like sailors at the free clinic.

Also, because sequencing between translation units is undefined and arbitrary, it often causes unexpected trouble.

TNx for answer.

You sure this is in c? does you know in each of version of this

in the old 89 too? (strangle how long i was unaware of that if this is in c)

As to order between modules (.o files i link in mingw) isnt it maybe

dependant on command line order of this files passed tolinker..?

As to order between modules (.o files i link in mingw) isnt it maybe

dependant on command line order of this files passed tolinker..?

It might be, but there is no standard so you can't depend on it. Might be now, then change when you update the compiler for example. That's the problem with relying on undefined behaviour.

As to order between modules (.o files i link in mingw) isnt it maybe
dependant on command line order of this files passed tolinker..?


It might be, but there is no standard so you can't depend on it. Might be now, then change when you update the compiler for example. That's the problem with relying on undefined behaviour.


The order is unspecified. "Undefined" means something else.

As to order between modules (.o files i link in mingw) isnt it maybe

dependant on command line order of this files passed tolinker..?

It might be, but there is no standard so you can't depend on it. Might be now, then change when you update the compiler for example. That's the problem with relying on undefined behaviour.

Well if i will build this once and for all it probably will not change at

runtime - so the formula of this order for mingw would be welcome -

does anybody maybe know?

(though i know it then it is limited to some environment only)

You really should heed the advice you have been given.

Another piece of advice: You should avoid global variables in general, and then this problem doesn't even exist. If you do use global variables for something, initialize them explicitly.

For instance, the `main' function in my C++ chess program starts with some initializations. The exact code looks like this (comments added for you):

int main() {
  // This is a hook so I can do any platform-specific initializations
  platform_initialize();
  
  // The pseudo-random number generator is an example of global state
  std::srand(std::fmod(now(), 1.0)*1000000);
  
  // Precompute some lookup tables
  initialize_magics();
  initialize_square_piece_tables();
  initialize_material_hash_table();
  
  // ...
}

Well I chceked it

c:\mingw\bin\gcc main.c -std=c99

and it does not compile, so maybe this is

not in c, though?

It certainly exists in both.

C89:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, it is initialized implicitly as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant.

C99:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these rules.

The ordering requirement existed even back in the K&R book from 1978. I don't know if it was specified in the earlier compilers, but even if the ordering wasn't specified (in order within the file, each file in unspecified order) since that is the easiest way to process it that is the likely behavior.

Now with that in mind, just because you can doesn't mean you should. **DON'T RELY ON STATIC INITIALIZATION**. I have seen actual shipped games where the static initialization took over ten seconds. We wanted to beat the previous team owners into oblivion when we did the port. The previous team masked it by mandatory splash screens.

Well I chceked it

c:\mingw\bin\gcc main.c -std=c99

and it does not compile, so maybe this is not in c, though?

Post your exact error message and the relevant lines and surrounding code indicated by the actual error messages. The concept of static initialization is probably not the bug.

You really should heed the advice you have been given.

many people give me advices with wich i generally agree (though i also

know 90% of this advices so it is a bit strange to read advices i know of)

I am asking on some things often not because i want to do this but just to know how it works

This topic is closed to new replies.

Advertisement