Created attachment 31875 [details] Source file to reproduce the issue This source code int f(int i) { const int a[] = {1, 2, 3, 4}; return a[i]; } int g(int i) { static const int a[] = {1, 2, 3, 4}; return a[i]; } generates different code with GCC 4.8.2 on x86_64 for f() and g(). In f(), the const array is really created on the stack, and initialized one element at a time, instead of being placed in .rodata as it is for g(). With GCC on ARM (4.7), both arrays from f() and g() are placed in .rodata, but the code to access them is different: .text .align 2 .global f .type f, %function f: @ args = 0, pretend = 0, frame = 16 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. str r4, [sp, #-4]! ldr r3, .L2 sub sp, sp, #20 mov ip, r0 ldmia r3, {r0, r1, r2, r3} add r4, sp, #16 stmdb r4, {r0, r1, r2, r3} add ip, r4, ip, asl #2 ldr r0, [ip, #-16] add sp, sp, #20 ldmfd sp!, {r4} bx lr .L3: .align 2 .L2: .word .LANCHOR0 .size f, .-f .align 2 .global g .type g, %function g: @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. ldr r3, .L5 add r0, r3, r0, asl #2 ldr r0, [r0, #16] bx lr .L6: .align 2 .L5: .word .LANCHOR0 .size g, .-g .section .rodata .align 2 .set .LANCHOR0,. + 0 .LC0: .word 1 .word 2 .word 3 .word 4 .type a.4057, %object .size a.4057, 16 a.4057: .word 1 .word 2 .word 3 .word 4 Note that on x86_64, clang generates the same code for f() and g() and even unifies both const arrays in .rodata. Is there anything in the C standard preventing a const array declared in a function from being put in .rodata or are those missed optimizations?
On Fri, 17 Jan 2014, sam at gcc dot gnu.org wrote: > Is there anything in the C standard preventing a const array declared in a > function from being put in .rodata or are those missed optimizations? If the object address can escape and the function can be called recursively, this would violate the requirement for distinct objects to have distinct addresses. (See discussion on comp.std.c, "uniqueness of automatic objects", Nov 2008; I'm not sure if there was a corresponding GCC bug report / fix.)
This is caused by checking TREE_ADDRESSABLE on the a decl which is correct thing to do but the issue is there is no addressing taking in the code (only an implicit one with a[i]: /* An array that is indexed by a non-constant cannot be stored in a register; we must be able to do address arithmetic on its address. Likewise an array of elements of variable size. */
This is also simply a gimplification issue. For larger arrays we initialize the stack with an aggregate copy from the constant pool.
Note that clang has this bug "in reverse": it unifies the arrays even when recursive calls are possible and address escapes the defining function (http://llvm.org/bugs/show_bug.cgi?id=18557).
*** Bug 94010 has been marked as a duplicate of this bug. ***
*** Bug 93102 has been marked as a duplicate of this bug. ***
Confirmed.