LWN.net Logo

GCC Explorer - an interactive take on compilation

GCC Explorer - an interactive take on compilation

Posted May 28, 2012 14:45 UTC (Mon) by gb (subscriber, #58328)
Parent article: GCC Explorer - an interactive take on compilation

Last not optimized thing i noticed:

const char* foo1(int id) {
const char* a[]={"One", "Two", "Three"};
return a[id];
}

const char* foo2(int id) {
static char* a[]={"One", "Two", "Three"};
return a[id];
}

it was a surprise for me that foo2 produces better code in gcc. :(


(Log in to post comments)

GCC Explorer - an interactive take on compilation

Posted May 28, 2012 15:57 UTC (Mon) by hummassa (subscriber, #307) [Link]

> it was a surprise for me that foo2 produces better code in gcc.

why? you _told_ the compiler you wanted a const array in the stack in foo1 and you wanted it in the "static area" (.data?) in foo2...

GCC Explorer - an interactive take on compilation

Posted May 28, 2012 16:25 UTC (Mon) by gb (subscriber, #58328) [Link]

> why? you _told_ the compiler you wanted a const array in the stack in foo1 and you wanted it in the "static area" (.data?) in foo2...

I think it is not expected to work in this way, for example, if you have a:

int f() {
int a=10;
return a;
}

The compiler would happily ignore that 'i told him to create variable a on stack' in favor of making code more optimal.

In same way, in case of

const char a[]={X1,X2,X3};

compiler knows that "a" is completely unused anywhere except inside this function, and I expect what it would optimize the code as much as possible. Maximum optimization here seems like creating whole array in static area and pushing each value to stack each time i am calling this function.

GCC Explorer - an interactive take on compilation

Posted May 28, 2012 16:28 UTC (Mon) by gb (subscriber, #58328) [Link]

err, typo s/and pushing each value to stack each time i am calling this function/instead of pushing each value to stack each time i am calling this function/

GCC Explorer - an interactive take on compilation

Posted May 28, 2012 16:51 UTC (Mon) by hummassa (subscriber, #307) [Link]

You seem to have forgotten something important: the compiler does not know if you want to retain the state from one call to the function to the next, and that would be an important side effect of static... and the reason why static (and static const) puts stuff on .data, as opposed to automatic (and automatic const) pushing values on the stack.

GCC Explorer - an interactive take on compilation

Posted May 28, 2012 21:09 UTC (Mon) by gb (subscriber, #58328) [Link]

Nope, i haven't forgotten this.

Compiler do know this perfectly, this static array is entirely inside function scope and it's trivial for compiler to find that static const case is absolutely same to plain const case, and that both are never used outside of scope of this function.

GCC Explorer - an interactive take on compilation

Posted May 29, 2012 18:53 UTC (Tue) by hummassa (subscriber, #307) [Link]

Anyway, arrays have to deal with many issues (aliasing, for instance) that preclude many optimization strategies; sometimes, the compiler programmers have to give some priority for the strategies that don't have to deal with that.

GCC Explorer - an interactive take on compilation

Posted May 29, 2012 9:41 UTC (Tue) by dgm (subscriber, #49227) [Link]

In C "const" does no imply any specific kind of storage. You can have register consts, static consts, auto consts, extern consts, and consts in the heap.

This is one of those places where C shows it's really a medium-level language, that gives you far more control over such little details than anything else.

GCC Explorer - an interactive take on compilation

Posted May 29, 2012 0:15 UTC (Tue) by cmccabe (guest, #60281) [Link]

You forgot to make the array const.

It should be const char * const a[].

Likewise, the static version has no const declaration at all, so I can only imagine that it's going to go in the writable portion of the data segment.

GCC Explorer - an interactive take on compilation

Posted May 29, 2012 9:44 UTC (Tue) by gb (subscriber, #58328) [Link]

> You forgot to make the array const.

It makes no difference, code generated for:
const char* const a[]={"One", "Two", "Three"};

and
const char* a[]={"One", "Two", "Three"};

is same.

> static version has no const declaration at all.

Sure, i just missed it, it would not compile without it, should be:
static const char* a[]={"One", "Two", "Three"};

GCC Explorer - an interactive take on compilation

Posted May 30, 2012 5:18 UTC (Wed) by jzbiciak (✭ supporter ✭, #5246) [Link]

Out of curiosity, in your "cosnt char *" version, are the strings "One", "Two" and "Three" allocated on the stack, or only the array a[]?

GCC Explorer - an interactive take on compilation

Posted May 30, 2012 7:51 UTC (Wed) by jamesh (guest, #1159) [Link]

The array contains pointers in all cases, so the actual strings would be in the read-only data section with any combination of "const".

GCC Explorer - an interactive take on compilation

Posted May 30, 2012 8:18 UTC (Wed) by jzbiciak (✭ supporter ✭, #5246) [Link]

Yep, it does seem to put it in rodata. I've seen enough shenanigans with initialized local arrays that I was prepared to hear it was strcpy()ing everything to local copies on the stack due to some obscure paragraph I missed in the standard. Thankfully, it's not that insane.

GCC Explorer - an interactive take on compilation

Posted May 30, 2012 11:28 UTC (Wed) by jamesh (guest, #1159) [Link]

That kind of thing only really happens when using a static initialiser for a character array. Since this was an array of pointers, that doesn't apply.

This is all part of the C standard, so I doubt you'd see much variation in any compiler made in the last 15 years (probably more).

GCC Explorer - an interactive take on compilation

Posted May 30, 2012 14:03 UTC (Wed) by jzbiciak (✭ supporter ✭, #5246) [Link]

Of course, GCC Explorer is showing us a C++ compiler, not a C compiler. There are many here who will point out that C++ isn't C or even a superset of C. ;-)

GCC Explorer - an interactive take on compilation

Posted May 30, 2012 15:32 UTC (Wed) by jamesh (guest, #1159) [Link]

Right, but you can mostly think of it as a superset of C for things that C compilers agreed on 15+ years ago. And this particular piece of code was just using basic types and syntax common to both languages, so you would expect it to behave similarly.

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds