如果复合文字出现在函数体外,则 对象有静态存储持续时间;否则,它有自动 与封闭块相关的存储持续时间。
我是否正确将“封闭区块”解释为“最里面的封闭区块”? (因为如果它不是最里面的那个,那是什么?) 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);}
}
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
答案 0 :(得分:5)
似乎没有任何充分的理由。我只是称它为编译器错误。
答案 1 :(得分:0)
考虑代码:
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);
}
这样的要求会大大地和不必要地破坏复合文字的有用性(因为代码也可以在没有它们的情况下编写)。更合理的规则将表明复合文字的生命周期延长,直到代码离开使用它的函数,或者创建它的表达式被重新执行,以先发生者为准。由于标准允许编译器延长自动对象的生命周期,但他们认为合适,编译器这样做的事实不应被视为错误。另一方面,有意识地比标准要求更有用的质量编译器应该明确地记录这个事实。否则,未来的维护者可能会声明任何依赖于这种明智行为的程序都是“有缺陷的”,并且编译器可以更有效率和#34;如果它不再支持他们。