mr5
mr5

Reputation: 3580

How const arrays are treated by C++ compilers

Are those constant arrays allocates space in memory or compilers are smart enough and decays this into something literal?

I will just provide an example here:

const int array[] = {
    1, 2, 3, 4, 5
};

Well, I just wanted to know nothing else.

Upvotes: 1

Views: 132

Answers (5)

ahoka
ahoka

Reputation: 412

The short answer is: it depends.

The long answer is:

If you compile this:

const int array[] = {
   1, 2, 3, 4, 5
};

int
main()
{
   return array[0];
}

You end up with this on x86/Linux (simplified):

       .globl  main
main:
       movl    $1, %eax
       ret

So yes, it will not be stored anywhere, but treated as a constant evaluated in compile time.

However, if you use it as this:

const int array[] = {
   1, 2, 3, 4, 5
};

int
main()
{
   return (long)array;
}

It becomes:

        .globl  main
main:
        leal    _ZL5array(%rip), %eax
        ret
        .section        .rodata
        .align 16
_ZL5array:
        .long   1
        .long   2
        .long   3
        .long   4
        .long   5

It ends up in section rodata, because you told the compiler you will actually need it as an array.

Upvotes: 2

Balog Pal
Balog Pal

Reputation: 17163

In theory it's completely up to the implementation. C++ standard defines behavior you get -- how you get it is left to magic.

In practice I expect every compiler (where the platform supports it to put that array in a const segment at compile time and use it from there directly.

As the optimizer goes, objects that are created 'const' right ahead have their state fixed (standard makes it undefined behavior to change them by any means), and data flow analyzers take that into account. Reading a value from the array from a known location can, and normally is substituted by the number.

Also IIRC using top-level const makes the object static by default, so unless you use 'extern' it will be private in the translation unit. And if nothing in the code requires it really (fetches were inlined by value), it will not be emitted at all.

Most compilers have option to emit the assembly/machine code output so you can inspect what it does for a particular implementation, or you can use an object file dumper to see the presence of the array.

Upvotes: 0

Spook
Spook

Reputation: 25927

Optimizers are actually very intelligent beings. For example, this code:

const int array[] = {1, 2, 3, 4, 5};

void show(int i)
{
    printf("%d\n", i);
}

int main(int argc, char * argv[])
{
    show(array[0]);
}

will mostly likely end up as:

void show()
{
    printf("%d\n", 1);
}

int main(int argc, char * argv[])
{
    show();
}

I guess, that optimizer will notice, that show may be easily inlined, so probably the code will be optimized even further:

int main(int argc, char * argv[])
{
    printf("%d\n", 1);
}

Upvotes: 0

Elazar
Elazar

Reputation: 21585

I believe that they can be optimized easily, if they are static. changing their values with some trick (such as const_casting it) is undefined behavior, so compilers will not care. anyway - you can check. gcc -O2 -S temp.c.

If the array is global and not static, the compiler should keep it in case some other compilation unit will need it. unless you do whole-program optimization.

Upvotes: 0

Jan Kundrát
Jan Kundrát

Reputation: 3816

There is an excellent blog post about data initialization in C++ by Olivier Goffart, one of the experts behind Qt.

Upvotes: 0

Related Questions