У меня есть следующий код, поведение которого мне непонятно. Может кто-нибудь, пожалуйста, помогите, как условный оператор оценивает следующий код и выводит ответ как 1
#включать
int main() {
bool delayMessages=0;
bool Delay = false;
delayMessages += Delay ? 1 : -1;
std::cout << "Hello world!"<<delayMessages;
return 0;
}
Ans: Hello world!1
Может кто-нибудь помочь, как оценивается этот код "delayMessages += Delay? 1: -1;"
Выражение в правой части оценивается как оператор if.
if (Delay == true)
return 1;
else
return -1;
Затем результат используется для присвоения +=
.
в Стандарт черновик С++ 20, который
7.6.19 (6) (Assignment and compound assignment operators)
The behavior of an expression of the form
E1 op= E2
is equivalent toE1 = E1 op E2
except that E1 is evaluated only once. [...]
Поскольку Delay == false
, тернарный оператор возвращает значение -1
. Тот факт, что вы работаете с bool
ean вместо int
, может создать впечатление, что вы получили +1
обратно.
Обратите внимание, что вы получаете предупреждение компилятора C4804:
warning C4804: '+=': unsafe use of type 'bool' in operation
Это неопределенное поведение? Нет.
7.6.19 (6) (Assignment and compound assignment operators)
[...] For += and -=, E1 shall either have arithmetic type or be a pointer to a possibly cv-qualified completely-defined object type. In all other cases, E1 shall have arithmetic type.
и
7.3.8 (2) (Integral conversions)
If the destination type is bool, see 7.3.14.
что говорит
7.3.14 (1) (Boolean conversions)
A prvalue of arithmetic, unscoped enumeration, pointer, or pointer-to-member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.
Таким образом, -1 преобразуется в true
, а true
печатается как 1.
Delay ? 1 : -1
оценивается как -1
, потому что Delay
ложно. Преобразование -1
в bool
дает true
, потому что только 0
преобразуется в false
. Затем распечатайте true
отпечатки 1
. Результат true
независимо от того, является ли Delay
true
или false
и 1
печатается в обоих случаях.
Используйте true
/ false
для логических значений и используйте целочисленный тип для целых чисел. Возможно, это то, что вы на самом деле хотели сделать:
int delayMessages=0;
bool Delay = false;
delayMessages += Delay ? 1 : -1;
std::cout << "Hello world!"<<delayMessages;
delayMessages += Delay ? 1 : -1;
В основном это означает, что если Delay
верно, то delayMessages += 1
(что равно 1), иначе delayMessages += -1
(что также равно 1).
Из стандарта C++ 17 (интегральные акции 7.6)
6 A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true becoming one.
и (7.14 логические преобразования)
1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. For direct-initialization (11.6), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.
и наконец (8.7 Аддитивные операторы)
1 The additive operators + and - group left-to-right. The usual arithmetic conversions are performed for operands of arithmetic or enumeration type.
Этот оператор выражения
delayMessages += Delay ? 1 : -1;
можно переписать как
delayMessages = delayMessages + ( Delay ? 1 : -1 );
Результатом выражения с условным оператором является -1
, потому что первое подвыражение (Delay
) оценивается как false
.
Так что на самом деле у вас есть
delayMessages = delayMessages + -1;
Переменная delayMessage
объявлена как
bool delayMessages=0;
имеет значение false
согласно цитатам из раздела 7.14.
В выражении с бинарным оператором плюс + преобразуется в целое число 0 согласно кавычкам (7.6 Интегральные промоушены) и 8.7 Аддитивные операторы и у вас есть
delayMessages = 0 + -1;
или
delayMessages = -1;
Опять же, согласно цитате 7.14 Логические преобразования, результирующее значение переменной delayMessage
будет true
.
Оператор << выводит логическое значение true как 1 в этом выражении.
std::cout << "Hello world!"<<delayMessages;
delayMessages
должен быть целочисленным, а не логическим типом