2

See the following:

static char start_marker;
static int var_1;
static int var_2;
/* ... */
static int var_n;
static char end_marker;

I want to initialize all variables in the section. Is the following code valid?

memset(&start_marker, 0, &end_marker-&start_marker);

Note that I can not use a struct here, because these fields are used by a db2 preprocessor as so called host variables.

paxdiablo
  • 772,407
  • 210
  • 1,477
  • 1,841
codymanix
  • 25,944
  • 18
  • 83
  • 142

6 Answers6

4

No, it isn't valid. The compiler can layout globals and statics however it wants.

Marcelo Cantos
  • 167,268
  • 37
  • 309
  • 353
2

First - by C standard static variables are preinitialized to zero - almost a FAQ, Static variable initialization?

If all you need is zero-initialized statics then there's nothing you need to do.

If you either want to zero a whole batch of static variables at some later point in time in one go, and/or require preinitialization of said batch to specific other values, you must instruct the linker (not the compiler) to put these variables into specifially known addresses. This is called a "section", and where these go can be controlled by linker scripts.
See example here:

http://www.math.utah.edu/docs/info/ld_3.html#SEC18

That gives an illustration how the default initialization code works.

You can even have the linker create / populate a symbol (pointer) with the address if your special section. In your C/C++ code, you'd do extern void* varblkaddr; extern size_t varblksize, and actually have the linker script create variables with these names, initialized to the addresses you chose, for you.

Actually, stackoverflow is a wonderful resource. This should help:

Fixed address variable in C

Community
  • 1
  • 1
FrankH.
  • 16,133
  • 2
  • 36
  • 54
1

Your code doesn't see to rely on order only but also on contiguity : I have neither guarantee here.

However, you should probably consider grouping all these variables in a struct.

icecrime
  • 66,755
  • 11
  • 95
  • 108
  • I mainly rely on the order of start_marker end_marker here, which seem a wrong assumption as the answers suggest – codymanix Dec 08 '10 at 12:46
1

As others have said, variables of static storage duration are always initialized. If you don't provide an explicit initializer, they're initialized to zero.

If you want to be able to reset them all to zero as a group later using memset, you need to put them all in a struct. Otherwise their locations are independent.

Keep in mind that from a standards perspective, memset to zero is not required to be the same thing as zero-initialization. It's allowed for null pointers and floating point zero values to have representations other than all-zero-bits. In practice, this is an idiotic liberty the standard gives implementations and you will never encounter such implementations in the modern world, so I would ignore the (non-)issue.

R.. GitHub STOP HELPING ICE
  • 195,354
  • 31
  • 331
  • 669
  • yes, depends on how platform independent you want to make your program – codymanix Dec 08 '10 at 17:51
  • I would not call it a platform issue. Some things (like the order bits are assigned to bitfields) are defined and documented by the implementation, either because the C standard requires them to be documented, or because otherwise it would be impossible to ensure ABI-compatibility of libraries. Other things, like the relative locations of independent variables, are something a program should never attempt to be aware of, and they may change with different versions of the compiler, optimization levels, presence of libraries, etc. Depending on them is not being platform-dep but just broken... – R.. GitHub STOP HELPING ICE Dec 08 '10 at 18:08
0

No, you have no guarantee that they are ordered in a specific way nor that they are contiguous in memory.

If you want to initialise them, use:

void initVars() {
    start_marker = 0;
    var_1 = 0;
    var_2 = 0;
    /* ... */
    var_n = 0;
    end_marker = 0;
}
paxdiablo
  • 772,407
  • 210
  • 1,477
  • 1,841
  • thats what Iam doing at the moment but it is slower (ok not that much) and there is the possibility that I forget one variable. – codymanix Dec 08 '10 at 14:46
0

Don't do that, in general this is just useless and error prone. Variables with static allocation are initialized to 0 from the start. There is no need to initialize them. In addition the compiler chooses the correct 0 to do so, e.g 0.0 for doubles or a null pointer constant for pointers etc.

If you want to make it clear for you and the readers of the code you could give it an explicit initializer, e.g

static int var_1 = { 0 };

This fall back initializer should always work. Even better, if you have a C99 compatible compiler, there are designated initializers:

static int arr[3] = { [0] = 0, [1] = 42,  };

The fields that are not mentioned in an initializer are again by default initialized to 0, here e.g the element arr[2].

All of this explicit initialization works for statically allocated variables or for stack variables (auto). memset is used way to often for that purpose. Just let the compiler do it for you. In the worst case he will just do a memset, but often he has a more clever way to do it.

Jens Gustedt
  • 72,200
  • 3
  • 92
  • 164
  • Thank you but the problem is that I to want to reinitialize them after I have used them, so that I can reuse them next time. It would be fatal for my app if old values would be in that variables – codymanix Dec 08 '10 at 13:00
  • Hm, using `static` variables then first of all smells of a designe flaw. If you really need them and if you have C99, even for reinitialization there is a similar way by using "compound literals". – Jens Gustedt Dec 08 '10 at 14:23
  • But compund literals requires structs too. – codymanix Dec 08 '10 at 14:44
  • @codymanix: sure. But as I said, if you use `static` variables as an easy mode of communication between different functions to that extent, your design is most probably flawed. Define a `state` structure for your application that holds the state, and separate out in a function exactly what you need to initialize that state. Wether or not such a state variable then is `static`, `auto` or malloced should matter much, then. – Jens Gustedt Dec 08 '10 at 15:10