Если я скомпилирую следующее в Ubuntu 16.04 / gcc 7.3
struct VecA {
float data[4];
};
struct VecB {
float x;
float y;
float z;
float w;
};
// Requires stack protection
VecA getA() {return {1.0f, 1.0f, 1.0f, 1.0f};}
// Does not require stack protection
VecB getB() {return {1.0f, 1.0f, 1.0f, 1.0f};}
Вот так:
g++ -O3 -c -o result test.cpp
objdump -d result
Я получаю:
0000000000000000 <_Z4getAv>:
0: 48 83 ec 18 sub $0x18,%rsp
4: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
b: 00 00
d: 48 89 44 24 08 mov %rax,0x8(%rsp)
12: 31 c0 xor %eax,%eax
14: f3 0f 7e 05 00 00 00 movq 0x0(%rip),%xmm0 # 1c <_Z4getAv+0x1c>
1b: 00
1c: 48 8b 44 24 08 mov 0x8(%rsp),%rax
21: 64 48 33 04 25 28 00 xor %fs:0x28,%rax
28: 00 00
2a: 75 09 jne 35 <_Z4getAv+0x35>
2c: 66 0f 6f c8 movdqa %xmm0,%xmm1
30: 48 83 c4 18 add $0x18,%rsp
34: c3 retq
35: e8 00 00 00 00 callq 3a <_Z4getAv+0x3a>
3a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
0000000000000040 <_Z4getBv>:
40: f3 0f 7e 05 00 00 00 movq 0x0(%rip),%xmm0 # 48 <_Z4getBv+0x8>
47: 00
48: 66 0f 6f c8 movdqa %xmm0,%xmm1
4c: c3 retq
То, что «выглядит» как защита стека linux, применяется к VecA
. Немного в защите, но я могу понять, как компилятор мог прийти к такому выводу.
Однако, это то, где я запутался:
Я не могу воспроизвести это на godbolt.org, даже если защита стека явно включена. Я могу сделать это для ОБА функций с -fstack-protector-all
, но это ожидаемо и неинтересно.
https://gcc.godbolt.org/z/ePR98P
Также, похоже, что в моей системе явное использование средства защиты стека снимает защиту с getA()
g++ -O3 -c -o -fstack-protector result test.cpp
objdump -d result
0000000000000000 <_Z4getAv>:
0: f3 0f 7e 05 00 00 00 movq 0x0(%rip),%xmm0 # 8 <_Z4getAv+0x8>
7: 00
8: 66 0f 6f c8 movdqa %xmm0,%xmm1
c: c3 retq
d: 0f 1f 00 nopl (%rax)
0000000000000010 <_Z4getBv>:
10: f3 0f 7e 05 00 00 00 movq 0x0(%rip),%xmm0 # 18 <_Z4getBv+0x8>
17: 00
18: 66 0f 6f c8 movdqa %xmm0,%xmm1
1c: c3 retq
Итак, мои вопросы:
Почему мои локальные результаты так сильно отличаются от того, что генерируется на godbolt.org?
Есть ли разумное объяснение поведению в моей системе? Особенно в отношении -fstack-protector
снятия защиты.
Разумно утверждать, что обе функции должны генерировать эквивалентную сборку в оптимизированном коде?
Редактировать
Строка полной версии:
g++ --version
g++ (Ubuntu 7.3.0-21ubuntu1~16.04) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.