const array vs static const array in a function
For example there is a function doing something. How should i declare and define an array inside the function i'd like to be allocated/initialized only once?
void someclass::somefunction(/*parameters here*/)
{
static const my_array[4] = {1,2,3,4}; // #1
/*or just*/
const my_array[4] = {1,2,3,4}; // #2
}
As far as i know in the case #1 "my_array" will be allocated in data 开发者_如何学Pythonsegment and initialized once at the first time of "somefunction" calling. But a colleague of mine made an supposition that the case #2 works in the same manner and there is no need to write "static" key-word.
So i'd like to ask does the standart say something about cases #1 & #2 and, if it does, what exactly? How should i define such type of arrays to be sured that it will be allocated/initialized only once?
Thank you.
The compiler will produce identical code for these two options.
Your example is quite trivial since the array involves plain-old-data (POD). The standard says that option 1 will be initialized each time somefunction
is run, but option 2 will be initialized the first time somefunction
is run. However, implementations are allowed to deviate from that so long as the result is indistinguishable to that specified in the standard, the so-called as-if rule.
In this case compilers write the arrays into read-only memory of the executable and there is no initialization at all at runtime. They can do this with POD types.
If you had an object that required runtime instantiation then things would be different. Consider the behaviour of the following program:
class MyObject
{
public:
MyObject() {}
};
void f()
{
const MyObject arr1[1] = { MyObject() };
static const MyObject arr2[1] = { MyObject() };
}
int main(int argc, char* argv[])
{
f();
f();
return 0;
}
The constructor for MyObject
runs 3 times.
My compiler (gcc 4.4.3
) generates identical code in these two cases.
Source code:
void f()
{
static const my_array[4] = {1,2,3,4}; // #1
}
void g()
{
const my_array[4] = {1,2,3,4}; // #2
}
The resulting assembly:
f:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
leave
ret
.cfi_endproc
g:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
leave
ret
.cfi_endproc
.section .rodata
.align 16
.type my_array.1594, @object
.size my_array.1594, 16
my_array.1594:
.long 1
.long 2
.long 3
.long 4
.align 16
.type my_array.1591, @object
.size my_array.1591, 16
my_array.1591:
.long 1
.long 2
.long 3
.long 4
I don't know whether other compilers behave in the same manner.
Declare and define it the most logical and clear way, and only if profiling shows it to be a bottleneck would I suggest changing the code.
In this case some compilers may very well generate the same code. Others may generate different code due to the slightly different initialization semantics (for example in some cases g++ protects initialization of statics with a mutex lock).
In fact the only way to know for sure for your particular compiler is to look at the disassembly.
Inside a function you might want to avoid using static
, since that also has the effect of initializing the declaration only once. So this type of declaration (used for sequential searching of structures) may lead to subtle bugs (the iterator mapi will only be initialized once):
static struct {
int a;
char c;
} const someConstantMap[] = { { 1, 'a' }, { 2, 'b'}, { 0 } },
*mapi = someConstantMap;
whereas omitting the static
will give you the const array and iterator as you would expect.
精彩评论