Take the 2-minute tour ×

I have a lot of constant arrays defined in several functions. Something like the following:

const float values[4] = {-4312.435f,  -432.44333f,  4.798, 7898.89};

After inspecting gcc assembler output I noticed that these constants are generated on each run of the functions. That's quite inefficient. I suspect that this is because C/C++ spec says that even if data is const, the compiler can't assume it won't be modified (e.g. through const_cast). Is it possible to force gcc think otherwise?

I want to keep these constants defined inside the bodies of the functions, because they are quite complex. Keeping constants near where they're used helps with the maintainability a lot.


Unfortunatelly, even when the constants are defined static, they are regenerated on the each run. I use -O3 if that helps.


Ok, sorry regarding the first edit, I need to investigate further. It seems that particular setup previously somehow didn't allow gcc to initialize the constants without regenerating them.


The problem was in my testcase, where I defined two arrays nearby, but one of them was intended to be generated. The assembler then misled me. Sorry again & thanks!

share|improve this question
What if you make the constants static? I think this will then place them on the stack. –  jwir3 Feb 16 '11 at 19:55
No, static specifier places constants outside stack. But surprisingly, gcc still regenerates them on each run of the function. –  user283145 Feb 16 '11 at 19:59
@jons34yp, can you post your code? How do you check, does gcc regenerate a constant or not? –  osgx Feb 16 '11 at 20:01
@jwir3: right idea, wrong reasoning. They already are being put on the stack - that is the default for all local variables. Using static causes the compiler to create the array only once, rather than recreating it each time it is used. –  Mac Feb 16 '11 at 20:01
I was not able to reproduce this behavior with a simple test function. Could you show a complete example function that produces bad code? –  Zack Feb 16 '11 at 20:05

5 Answers 5

up vote 10 down vote accepted

Declare them with the static keyword.

Edit: responding to your comment so I can show you some code:

This is the expected behavior. Are you doing or seeing something different?

$ cat foo.c++
int main(void)
    static const float foos[] = {1.234f, 5.678f, 9.012f};
    return 0;
$ g++ -S foo.c++
$ cat foo.s
    .file   "foo.c++"
.globl main
    .type   main, @function
    .cfi_personality 0x3,__gxx_personality_v0
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    movl    $0, %eax
    .size   main, .-main
    .section    .rodata
    .align 4
    .type   _ZZ4mainE4foos, @object
    .size   _ZZ4mainE4foos, 12
    .long   1067316150
    .long   1085649453
    .long   1091580199
    .ident  "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
    .section    .note.GNU-stack,"",@progbits
share|improve this answer
Unfortunatelly gcc still regenerates the constants –  user283145 Feb 16 '11 at 19:59
@jons34yp: What do you mean by regenerates the constants? I tried a small example myself, and a function containing const float values[4] = {1,2,3,4}; was compiled as a lot of mov instructions, but the corresponding function using static did not contain those mov instructions. –  aschepler Feb 16 '11 at 20:07
try to use a some of values in the function. –  osgx Feb 16 '11 at 20:13
@jons34yp, see edit above. With static there are no instructions which "regenerate" any constants here. –  rlibby Feb 16 '11 at 20:14
@osgx, what are you getting at? If you actually use them then the compiler will generate instructions to move the values from the memory location at _ZZ4mainE4foos to (floating point) registers. –  rlibby Feb 16 '11 at 20:27

The compiler actually can assume that values defined as const will never change. (Things accessed via a const variable are another story; I'm only talking about cases when the definition is visible and has const.) The gotcha that is getting ya here is that the Standard says if you call your function recursively, the address of values will be different each time.

So use the language feature that means the declaration refers to the same thing each time the function is called. That is, a static function variable:

share|improve this answer
This is a good answer. +1 for explaining rather than just giving the answer. –  jwir3 Feb 16 '11 at 20:01

Change the definition to


Static arrays will not be placed in stack of function, so they will be not regenerated for each function call.

You can also try to move this array outside from function (make it a global array with some prefix like function1_values).


If you counts the "flds" or "movss" instuctions as regenerating - the are not. The constants will be stored in .rodata section of the elf file, but to use them, compiler must load them into registers. So fld & movss will only load the constant from memory and it is impossible to get value from memory without loading it.

The sample code:

int function4(float *a, int sz)
    int i;
    return i;

gcc-4.5.2 -O3 a.c -fverbose-asm -mfpmath=sse -march=native -S

Assembelr for loop body:

    movl    -20(%ebp), %ecx # %sfp, D.2677
    leal    (%edx,%ecx), %ecx       #, D.2677  
    movss   .LC0, %xmm0     #, tmp192     << THIS is a constant loading
    mulss   (%edx,%edi), %xmm0      #* prephitmp.46, tmp192
    movss   .LC1, %xmm1     #, tmp179
    mulss   (%edx,%esi), %xmm1      #* prephitmp.46, tmp179
    addss   %xmm1, %xmm0    # tmp179, tmp192
    movss   .LC2, %xmm1     #, tmp183
    mulss   (%edx,%ebx), %xmm1      #* prephitmp.46, tmp183
    addss   %xmm1, %xmm0    # tmp183, tmp192
    movss   .LC3, %xmm1     #, tmp187
    movl    -16(%ebp), %ebx # %sfp,

And constants are stored at .rodata:

    .section        .rodata.cst4,"aM",@progbits,4
    .align 4
    .long   -981023877
    .align 4
    .long   -1009239873
    .align 4
    .long   1083803959
    .align 4
    .long   1173804831
share|improve this answer
const already means internal linkage, static is superfluous –  Gene Bushuyev Feb 16 '11 at 20:12
Actually, in my example the const array and the static const array generate the same code (!) –  osgx Feb 16 '11 at 20:31
@Gene Bushuyev, there can be 2 cases: global const array and local const array (declared in the function) –  osgx Feb 16 '11 at 20:32

Place all your


in a separate .cpp file.

Declare them extern in the file that uses these arrays

extern const float values[4];

Though, as mentioned in the comments, profile this (in a real app where these arrays might be thrown out of the l1/l2 caches). This might, for non-intutive reasons, decrease performance.

share|improve this answer

I don't understand where you see the problem, compiler does a reasonable thing optimizing away the constants. You can prevent that by requiring external linkage:

extern const float values[4];
share|improve this answer

Your Answer

