#include <array>
#include <cassert>
class P {
public:
P() : _value(nullptr) {}
~P() { delete _value; }
private:
char *_value;
};
void foo() {
if(std::array<P, 4>().size() != 4)
assert(false);
}
The function foo()
creates a temporary array to check the size is what the programmer expected. With -O1
or higher g++ figures out the assert
will not fail and the call to __assert_fail
is removed from the generated code. But g++ still generates code to first construct and then destruct the now unused array.
g++ -std=c++11 -O3 [4.8.2]:
0000000000000000 <_Z3foov>:1
0: 55 push %rbp1
1: 66 0f ef c0 pxor %xmm0,%xmm01
5: 53 push %rbx1
6: 48 83 ec 28 sub $0x28,%rsp1
a: 66 0f 7f 04 24 movdqa %xmm0,(%rsp)1
f: 48 8d 5c 24 20 lea 0x20(%rsp),%rbx1
14: 48 89 e5 mov %rsp,%rbp1
17: 66 0f 7f 44 24 10 movdqa %xmm0,0x10(%rsp)1
1d: 0f 1f 00 nopl (%rax)1
20: 48 83 eb 08 sub $0x8,%rbx1
24: 48 8b 3b mov (%rbx),%rdi1
27: e8 00 00 00 00 callq 2c <_Z3foov+0x2c>1
2c: 48 39 eb cmp %rbp,%rbx1
2f: 75 ef jne 20 <_Z3foov+0x20>1
31: 48 83 c4 28 add $0x28,%rsp1
35: 5b pop %rbx1
36: 5d pop %rbp1
37: c3 retq 1
clang on the other hand removes all code except the return statement.
clang -std=c++11 -O3:
0000000000000000 <_Z3foov>:1
0: c3 retq 1
Just bad luck with g++ or is there a reason for the difference?
Because there could be side effects in the constructor of
std::array
. However, as g++ and clang don't use the same standard library (libstdc++ for g++ and libc++ for clang).For the question why does clang remove the code, maybe that in libc++ the
std::array
's constructor in inlined, so the optimizer can see that there is no side effects, therefore need to keep the code.