C++将布尔强制转换为int标准

C++ casting bool to int - standard

本文关键字:int 标准 转换 布尔强 C++      更新时间:2023-10-16

在将标准转换为integer类型后,我不知道该标准是否说明了bool类型类型的可能值。

例如以下代码:

#include <iostream>
using namespace std;
int main() {
    bool someValue=false;
    *((int*)(&someValue)) = 50;
    cout << someValue << endl;
    return 0;
}

打印1,即使它被迫存储值50。标准对此有什么规定吗?或者编译器正在为bool类型生成一些方法,如:

operator int(){
    return myValue !=0 ? 1 : 0;
}

为什么铸造如下:

reinterpret_cast<int>(someValue) = 50;

错误禁止

错误:从类型"bool"到类型"int"的强制转换无效

(对于以上所有I用户GCC 5.1编译器。)

您使用它的方式显示出UB,因为您在bool变量的边界之外写入,并且您打破了严格的别名规则。

但是,如果您有一个bool并希望将其用作int(当您希望根据某些条件对数组进行索引时,通常会发生这种情况),则无论发生什么,标准都要求true bool转换为1false bool转换成0(UB显然被排除在外)。

例如,这保证输出52should_add == true一样长。

int main(){
    int arr[] = {0, 10};
    bool should_add = 123;
    int result = 42 + arr[should_add];
    std::cout << result << 'n';
}

此行*((int*)(&someValue)) = 50;至少是非标准的。实现可以对bool(比如1或2个字节)使用比int(比如4个字节)更小的秩。在这种情况下,您将写过该变量,可能会擦除其他变量。

不管怎样,正如您在评论中所说,由于严格的别名规则,编译器几乎可以将通过投射指针进行的任何访问视为未定义行为。唯一几乎合法的(对于严格的混叠规则)是:

*((char *) &someValue) = 50; 

在一个小endian系统上,以及

*(((char *) &someValue) + sizeof(bool) - 1) = 50; 

在big-endian上(字节访问仍未被禁止)。

无论如何,由于标准没有指定bool的表示形式,直接在bool中编写某些内容可能会导致true或false,具体取决于实现。例如,一个实现可以只考虑最低级别的位(如果val&1为1,则为true,否则为0),另一个实现则可以考虑所有位(对于任何非0值为true,对于仅为0为false)。标准中唯一规定的是,0的转换会导致错误,而非0的转换则会导致正确。


但标准规定是从布尔到int的转换:

4.5整体促销[conf.prom]


bool类型的prvalue可以转换为int类型的prvalue,false变为零,true变为true成为一体。

因此,这充分解释了显示bool只能给出0或1——即使像前面调用UB的操作一样,这里也可能发生任何事情,包括这个显示

You invoked Undefined Behaviour - shame on you