6.5.2.5p5表示
如果复合文本出现在函数体之外,则对象具有静态存储持续时间;否则,它具有与封闭块相关联的自动存储持续时间。
我把这里的"封闭块"理解为"最里面的封闭块"对吗?(因为如果它不是最里面的,那是哪个?)Why are gcc and clang behaving as if the lifetime of a literal were its enclosing function?
示例:
long foo(long*);
void call_foo()
{
{foo(&(long){42});}
{foo(&(long){42});}
{foo(&(long){42});}
{foo(&(long){42});}
}
//for comparison
void call_foo2()
{
{long x=42;foo(&x);}
{long x=42;foo(&x);}
{long x=42;foo(&x);}
{long x=42;foo(&x);}
}
- O3时gcc/clang生成的代码:
call_foo:
sub rsp, 40
mov rdi, rsp
mov QWORD PTR [rsp], 42
call foo
lea rdi, [rsp+8]
mov QWORD PTR [rsp+8], 42
call foo
lea rdi, [rsp+16]
mov QWORD PTR [rsp+16], 42
call foo
lea rdi, [rsp+24]
mov QWORD PTR [rsp+24], 42
call foo
add rsp, 40
ret
call_foo2:
sub rsp, 24
lea rdi, [rsp+8]
mov QWORD PTR [rsp+8], 42
call foo
lea rdi, [rsp+8]
mov QWORD PTR [rsp+8], 42
call foo
lea rdi, [rsp+8]
mov QWORD PTR [rsp+8], 42
call foo
lea rdi, [rsp+8]
mov QWORD PTR [rsp+8], 42
call foo
add rsp, 24
ret
2条答案
按热度按时间t9aqgxwy1#
这似乎没有什么好的理由,我只会称之为编译器bug。
jvidinwx2#
考虑代码:
按照标准的编写方式,复合字面值只有在对
p
的赋值在包含它的表达式中执行时才可用,而不需要statement
来控制不能单独通过条件运算符控制的内容;更改代码以使用if
语句而不是?:操作员将需要大量返工:这样的要求将大大地和不必要地削弱复合文字的有用性(因为没有它们也可以写代码)。一个更合理的规则是,复合字面值的生存期延长到代码离开使用它的函数,或者创建它的表达式被重新执行,以先发生者为准。由于标准允许编译器以他们认为合适的方式延长自动对象的生存期,编译器这样做的事实不应该被认为是bug。另一方面,一个质量好的编译器,如果有意地想比标准要求的更有用,应该明确地记录这个事实。2否则,将来的维护者可能会宣称任何依赖于这种可感知行为的程序是“有缺陷的”,如果编译器不再支持它们,编译器可能会更“有效”。