I agree with you on this example. But in my original code, as Jonathan pointed out, is not recursive and the address of "a" does not escape the function in any way. I believe it is valid transformation.
BTW, LLVM compiles your example still by moving const array to rodata, which I think is wrong and will fail the test. Cheers, Bingfeng On Thu, Apr 21, 2016 at 3:41 AM, lh_mouse <lh_mo...@126.com> wrote: > See this example: http://coliru.stacked-crooked.com/a/048b4aa5046da11b > > In this example the function is called recursively. > During each call a pointer to that local areay is appended to a static array > of pointers. > Should a new instance of that local array of const int be created every time, > abort() will never be called. > Since calling a library function is observable behavior, clang's optimization > has effectively changed that program's behavior. Hence I think it is wrong. > > [code] > #include <stdlib.h> > > static const int *ptrs[2]; > static unsigned recur; > > void foo(){ > const int a[] = {0,1,2,3,4,5,6,7,8,9}; > ptrs[recur] = a; > if(recur == 0){ > ++recur; > foo(); > } > if(ptrs[0] == ptrs[1]){ > abort(); > } > } > > int main(){ > foo(); > } > [/code] > > ------------------ > Best regards, > lh_mouse > 2016-04-21 > > ------------------------------------------------------------- > 发件人:Jonathan Wakely <jwakely....@gmail.com> > 发送日期:2016-04-21 01:51 > 收件人:lh_mouse > 抄送:Bingfeng Mei,gcc > 主题:Re: Why does gcc generate const local array on stack? > > On 20 April 2016 at 18:31, lh_mouse wrote: >> I tend to say clang is wrong here. > > If you can't detect the difference then it is a valid transformation. > >> 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.' > > How do you tell the difference between a const array that is recreated > each time and one that isn't? > >> 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: > > If the object's address doesn't escape from the function then I can't > think of a way to tell the difference. > >