变量定义到C++布尔值转换

Variable definition to boolean value conversion in C++

本文关键字:布尔值 转换 C++ 定义 变量      更新时间:2023-10-16

我发现下面的代码在 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] 中。

1

个条件:  表达  attribute-specifier-seqoptdecl-specifier-seq declarator brace-or-equal-initializer

4 不是表达式的条件是声明 声明符不得指定函数或数组。 decl-specifier-seq 不应定义类或枚举。如果 自动类型说明符出现在 decl-specifier-seq 中,类型 声明的标识符是从初始值设定项推导的,如下所述 在 [dcl.spec.auto] 中。

6 作为初始化声明的条件的值 switch 语句以外的语句是声明的值 变量上下文转换为布尔值。如果该转换是 格式不正确,程序格式不正确。条件的值 是 switch 语句中的初始化声明 是 的值 声明的变量(如果它具有整型或枚举类型),或 隐式转换为整型或枚举类型的变量 否则。作为表达式的条件的值是值 的表达式,在上下文中转换为布尔值以表示语句其他 比开关;如果该转换格式不正确,则程序是 格式不正确。条件的值将简称为简单 用法明确的"条件"。

7 如果条件可以在语法上解析为 表达式或块范围名称的声明,它被解释 作为声明。

8 在条件的 decl-说明符-seq 中,每个 decl-说明符 应为类型说明符或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 语句、for-range 声明中声明的名称,以及 在 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 的整数。从其他值转换时,如果值为零,它将布尔值解析为 false,则每隔一个数字变为 true。

这样可以轻松检查指针(也可以解释为数字),其中值为 0 的指针是空指针。

任何赋值语句的结果都是赋值后左操作数的值。

值零(对于整型枚举、浮点枚举和无作用域枚举)以及空指针和空指针指向成员的值变为 false。所有其他值都变为 true。

所以这里 int x 的值为 7 变为 true。