6.5.2.5p5说
如果复合文字发生在函数正文之外,则对象具有静态存储持续时间;否则,它具有与封闭块关联的自动存储时间。
我把这里的“封闭块”解释为“最里面的封闭块”是正确的吗?(因为如果不是最里面的,那是哪一个?) 为什么gcc和clang表现得好像文字的生命周期是它的封闭功能呢?
示例:
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);}
}gcc/clang在-O3生成的代码:
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发布于 2017-12-07 12:47:39
这似乎没有任何好的理由。我会管它叫编译器错误。
发布于 2017-12-15 20:58:10
考虑一下守则:
void whatever(void)
{
THING *p;
...
if (condition1)
p=&(THING){...whatever...};
...
doSomethingWith(p);
}按照标准的编写方式,只有在由由p控制的唯一非复合语句执行分配给if的情况下,复合文字才是可用的;更改代码以使if控制复合语句将需要进行大量的重新工作:
void whatever(void)
{
THING *p,temp_thing;
...
if (condition1)
{
temp_thing = (THING){...whatever...};
// Or else temp_thing.field1 = value1; temp_thing.field2=value2; etc.
p=&temp_thing;
}
...
doSomethingWith(p);
}这样的要求会在很大程度上不必要地破坏复合文字的有用性(因为没有它们也可以编写代码)。一个更合理的规则将指出,复合文字的生存期将延长,直到代码离开使用它的函数,或者重新执行创建它的表达式,无论哪种情况先发生。由于标准允许编译器延长自动对象的生存期,尽管他们认为合适,但编译器这样做的事实不应被视为错误。另一方面,有意识地比标准要求更有用的高质量编译器可能应该显式地记录这一事实。否则,未来的维护人员可能会声明,任何依赖于这种合理行为的程序都是“有缺陷的”,如果编译器不再支持它们,那么编译器就会更“高效”。
https://stackoverflow.com/questions/47691857
复制相似问题