G++ ошибка? (bool_val? 0: 1) не возвращает ни 0, ни 1
Я воспроизведу проблему этой простой демонстрацией:
// bool_test_func.cpp
#include <stdio.h>
void func(bool* b) {
int a = (*b ? 0 : 1);
printf("%d\n", a); // EXPECT ether 0 or 1 here
}
// bool_test.cpp
void func(bool* b);
int main() {
int n = 128;
func((bool*)&n);
return 0;
}
-O0 скомпилировать и запустить:
g++ -g -O0 -Wall -o bool_test bool_test.cpp bool_test_func.cpp
[email protected]:~/testing/c++$ ./bool_test
0
-O1 скомпилировать и запустить (неожиданный результат):
g++ -g -O1 -Wall -o bool_test bool_test.cpp bool_test_func.cpp
[email protected]:~/testing/c++$ ./bool_test
129
Когда я проверяю код -O2 ASM, я думаю, что это ошибка g++, g++-код оптимизации всегда считает значение bool равно 1 или 0:
00000000004005e6 :
4005e6: 48 83 ec 08 sub $0x8,%rsp
4005ea: 0f b6 37 movzbl (%rdi),%esi
4005ed: 83 f6 01 xor $0x1,%esi #just XOR the bool val
4005f0: 40 0f b6 f6 movzbl %sil,%esi
4005f4: bf 94 06 40 00 mov $0x400694,%edi
4005f9: b8 00 00 00 00 mov $0x0,%eax
4005fe: e8 9d fe ff ff callq 4004a0
400603: 48 83 c4 08 add $0x8,%rsp
400607: c3 retq
400608: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
40060f: 00
gcc версия 4.9.2 (Debian 4.9.2-10)
Это поведение g++ по дизайну? Как я могу отключить эту неправильную оптимизацию?
Благодаря ~
Ответы
Ответ 1
Я думаю, что это ошибка g++.
Приходится с уважением не соглашаться.
Как отключить эту неправильную оптимизацию?
Даже если это возможно, это на самом деле не так: -)
Вы передаете указатель non-bool в качестве указателя bool (базовый элемент не относится к типу bool), и я уверен, что это (известное как punning) вызывает undefined поведение.
Следовательно, код может делать все, что захочет.
Вы можете подумать о прототипе void func(bool* b)
как о контракте, в котором вы согласны, чтобы когда-либо передавать указатели на значения bool
. Если вы нарушите этот контракт, все ставки будут отключены. В этом конкретном случае ваш код:
int a = (*b ? 0 : 1);
говорит ему преобразовать false в 1 и true в 0. Если вы должны были ввести действительный ввод (false/0
или true/1
), то xor input, 1
будет именно то, что нужно сделать.
Однако, поскольку вы даете 128
, xor
приводит к 129
.