[英]Variable definition to boolean value conversion in C++
我发现以下代码在 C++98 及更高版本中有效:
if (int x = 7) { // int x; if (x = 7) makes sense
std::cout << x << '\n'; // 7 is printed
}
问题:控制变量定义到布尔表达式的转换的规则是什么?
如果它像下面那样,那么 b/c if 条件是一个赋值表达式,它会计算为一个整数:
int x;
if (x = 7) {
std::cout << x << '\n';
}
赋值表达式的结果是赋值目标,在本例中为x
。 由于bool(7)
为真,条件为真。
此功能的一个常见用法更有用,如下所示:
if (auto* x = get_some_pointer())
// use x, which is known to be not null
变量在哪里声明与它无关。 按照你的例子,这会做同样的事情:
int x;
if (x = 7)
// ...
管理这部分语法的规则在[stmt.pre]
健康)状况:\n 表达\n 属性说明符-seq opt decl-specifier-seq声明符大括号或等号初始化器4不是表达式的条件是声明 ([dcl.dcl])。 声明符不应指定函数或数组。 decl-specifier-seq 不应定义类或枚举。 如果 auto 类型说明符出现在 decl-specifier-seq 中,则声明的标识符的类型是从初始化程序中推导出来的,如 [dcl.spec.auto] 中所述。
6在 switch 语句以外的语句中作为初始化声明的条件的值是根据上下文转换为 bool 的声明变量的值。 如果该转换格式错误,则程序格式错误。 在 switch 语句中作为初始化声明的条件的值是声明变量的值,如果它具有整数或枚举类型,或者该变量隐式转换为整数或枚举类型,否则。 作为表达式的条件的值是表达式的值,对于 switch 以外的语句,上下文转换为 bool; 如果该转换格式错误,则程序格式错误。 条件的值将简单地称为“条件”,其中用法是明确的。
7如果条件可以在语法上解析为表达式或块范围名称的声明,则将其解释为声明。
8在条件的 decl-specifier-seq 中,每个 decl-specifier 要么是类型说明符,要么是
constexpr
。
上述文本中的condition
是出现在if (condition)
, while (condition)
和switch (condition)
的语法产生式中的语法元素。 [stmt.stmt] 中大多数其他提到的condition
在转换为布尔值或整数值(在开关中)后处理其值。 而基于价值的行为正是人们所期望的。
在别处提到的唯一另一件值得注意的事情是声明关于其声明区域的行为。 例如,在 if 语句中
if(auto handle = getHandle())
handle->foo();
else
handle->bar();
该名称在两个分支中均可用。 但这在[basic.scope.block] 中提到
3在 init-statement、for-range-declaration 以及 if、while、for 和 switch 语句的条件中声明的名称是 if、while、for 或 switch 语句(包括受控语句)的局部名称,并且不应在该语句的后续条件中或在受控语句的最外层块(或对于 if 语句,任何最外层块)中重新声明。 [ 例子:
if (int x = f()) { int x; // error: redeclaration of x } else { int x; // error: redeclaration of x }
— 结束示例 ]
与 C 一样,C++ 布尔值被视为值为 0 或 1 的整数。当从其他值转换时,如果值为 0,它会将布尔值解析为 false,如果值为零,则每隔一个数字变为 true。
这可以轻松检查指针(也可以解释为数字),其中值为 0 的指针是空指针。
任何赋值语句的结果都是赋值后左操作数的值。
零值(对于整数、浮点和无作用域枚举)以及空指针和指向成员的空指针值变为假。 所有其他值都变为真。
所以这里 int x 的值为 7 变为真。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.