- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
#include <iostream>
using namespace std;
void foo()
{
int i = 0xffffffff;
cout << i << endl;
}
void bar()
{
bool b;
if(b)
{
cout << "true" << endl;
}
if(!b)
{
cout << "false" << endl;
}
}
int main()
{
foo();
bar();
return 0;
}
Использование неинициализированной переменной = UB. ГЦЦ использует xor 1 чтобы обратить значение, т.к. не ожидает что там будет что-то кроме 0 или 1. Поэтому если там что-то другое получим один и тот же результат когда будем сравнивать с нулём.
Компилятор ругается на оба случая, как бэ говоря "Не делай этого".
Кто сделал — ССЗБ.
За пример — спасибо, я вчера полчаса угробил пытаясь заставить бул себя так вести.
Это о чём вообще?
> Использование неинициализированной переменной = UB.
Ага.
> ГЦЦ использует xor 1 чтобы обратить значение, т.к. не ожидает что там будет что-то кроме 0 или 1.
А у этого какие-то подтверждения есть? Кстати, мой вариант кода эту версию не подтверждает.
У меня подозрения, что он просто выпиливает проверку, поскольку значение неопределённое.
int i = 0xffffffff нужен только чтобы на стеке мусор остался, иначе там будут нули.
Не проверяется:
<No output: Error: stdout maxBuffer exceeded.>
> Он прав насчет xor
Почему тогда в моём варианте только true?
Там можно посмотреть асмовыхлоп
> Почему тогда в моём варианте только true?
Потому что зависит от компилятора и флагов
Потому что UB.
Запихнуть его в простой инт не выходит, так что результат implementation defined, не UB, я ошибся. (4.7.3 If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.)
В данном случае "лишний" бит записали заместо знакового. Если бы этот бит был бы нулевым: То получим INT_MAX (на конкретном компиляторе, implementation defined же)