I tend to say clang is wrong here. Quoting the standard:
ISO/IEC WG14 Draft N1570 (Programming languages — C): [quote] 6.2.2 Linkages of identifiers 6 The following identifiers have no linkage: an identifier declared to be anything other than an object or a function; an identifier declared to be a function parameter; a block scope identifier for an object declared without the storage-class specifier extern. 6.2.4 Storage durations of objects 6 An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration, as do some compound literals. ... 7 For such an object that does have a variable length array type, its lifetime extends from the declaration of the object until execution of the program leaves the scope of the declaration.35) If the scope is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. [/quote] Your identifier 'a' has no linkage. Your object designated by 'a' does not have a storage-class specifier. So it has automatic storage duration and 6.2.4/7 applies: 'If the scope is entered recursively, a new instance of the object is created each time.' Interesting enough, ISO C doesn't say whether distinct objects should have distinct addresses. It is worth noting that this is explicitly forbidden in ISO C++ because distinct complete objects shall have distinct addresses: ISO/IEC WG21 N4582 (Working Draft, Standard for Programming Language C++) : [quote] 1.9 Program execution [intro.execution] 7 An instance of each object with automatic storage duration (3.7.3) is associated with each entry into its block. Such an object exists and retains its last-stored value during the execution of the block and while the block is suspended (by a call of a function or receipt of a signal). 1.8 The C++ object model [intro.object] 6 Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address of the first byte it occupies. Two objects that are not bit-fields may have the same address if one is a subobject of the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise, they shall have distinct addresses.4 [/quote] ------------------ Best regards, lh_mouse 2016-04-20 ------------------------------------------------------------- 发件人:Bingfeng Mei <bingfeng....@broadcom.com> 发送日期:2016-04-20 23:38 收件人:gcc 抄送: 主题:Why does gcc generate const local array on stack? Hi, I came across the following issue. int foo (int N) { const int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; return a[N]; } Compile with x86 O2 foo: .LFB0: .cfi_startproc movslq %edi, %rdi movl $0, -56(%rsp) movl $1, -52(%rsp) movl $2, -48(%rsp) movl $3, -44(%rsp) movl $4, -40(%rsp) movl $5, -36(%rsp) movl $6, -32(%rsp) movl $7, -28(%rsp) movl $8, -24(%rsp) movl $9, -20(%rsp) movl -56(%rsp,%rdi,4), %eax ret The array is placed on stack and GCC has to generate a sequence of instructions to initialize the array every time the function is called. On the contrary, LLVM moves the array to global data and doesn't need initialization within the function. If I add static to the array, GCC behaves the same as LLVM, just as expected. Is there some subtle C standard issue or some switch I didn't turned on? I understand if this function is recursive and pointer of the array is involved, GCC would have to maintain the array on stack and hence the initialization. But here the code is very simple. I don't understand the logic of generated code, or maybe missing optimization opportunity? Thanks, Bingfeng Mei