开发者

Is the order of variables defined by the standard?

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 varia开发者_如何转开发bles.


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


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


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.


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.


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;
}


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜