我阅读了这个问题的答案:为什么在c++中一个字符和一个bool大小相同?,并进行了一个实验,以确定_Bool和bool内存中分配的字节大小(我知道bool是stdbool.h中_Bool的宏,但为了完整起见,我也使用了它) C中的对象,以及在我的实现LinuUbuntu12.4上的C++中的bool对象:
C组:
#include <stdio.h>
#include <stdbool.h>   // for "bool" macro.
int main()
{
    _Bool bin1 = 1;
    bool bin2 = 1; // just for the sake of completeness; bool is a macro for _Bool.    
    printf("the size of bin1 in bytes is: %lu \n",(sizeof(bin1)));
    printf("the size of bin2 in bytes is: %lu \n",(sizeof(bin2)));  
    return 0;
}输出:
the size of bin1 in bytes is: 1
the size of bin2 in bytes is: 1对于C++:
#include <iostream>
int main()
{
    bool bin = 1;
    std::cout << "the size of bin in bytes is: " << sizeof(bin);
    return 0;
}输出:
the size of bin in bytes is: 1 因此,布尔类型的对象,无论是特定的C或C++,都占用内存中的1字节(8位),而不仅仅是1位。
我的问题是:
bool和_Bool类型的对象和C++中的bool类型的对象只能够存储0或1的值,如果它们在内存中占用一个字节,可以容纳256个值?当然,它们的目的只是表示0和1或true和false的值,但是哪个单元或宏决定它只能存储0或1。
另外,但不是我的主要问题:
*无意中,我的意思是:修改为“不可探测的手段”- 什么是“无法检测的意思”,它们如何改变C/C++程序的对象?或不适当的分配f.e。bool a; a = 25;。
发布于 2020-01-22 15:54:39
C语言限制了可以存储在_Bool中的内容,即使它能够保存除0和1以外的其他值。
C标准的第6.3.1.2节提到了关于转换到_Bool的以下内容
当将任何标量值转换为
_Bool时,如果该值比较等于0,则结果为0;否则,结果为1。
C++17标准在第7.14节中有类似的语言:
可以将算术、非作用域枚举、指针或成员类型指针的prvalue转换为
bool类型的prvalue。零值、空指针值或空成员指针值转换为false;任何其他值都转换为真。对于直接初始化(11.6),可以将std::nullptr_t类型的prvalue转换为bool类型的prvalue;结果值为false。
因此,即使您试图将其他值赋值给_Bool,语言也会将该值转换为0或1表示C,将值转换为true或false表示C++。如果试图通过指向不同类型的指针写入_Bool来绕过这一点,则调用未定义行为。
发布于 2020-01-22 16:07:23
回答C++:
因此,布尔类型的对象,无论是特定的C或C++,都占用内存中的1字节(8位),而不仅仅是1位。
这仅仅是因为C++内存模型中的基本存储单元是字节。
为什么类型为.
bool在C++中的对象只能存储0或1的值,如果它们在内存中占用一个字节,可以容纳256个值? 但是哪个单元或宏决定它只能存储0或1?
这里的假设是错误的。在C++中,bool不包含0或1,它包含false或true:http://eel.is/c++draft/basic.fundamental#10。
如何在内存中表示这两个值是,直到实现为止。实现可以使用0和1,或者0和255,或者0和<any nonzero value>,或者它真正想要的任何东西。在检查0或1内存时,不能保证找到bool,因为.
bool,则根据通常的规则:http://eel.is/c++draft/conv.bool#1,将其隐式转换为true或false。0 false或1,则它将被隐式转换为true:http://eel.is/c++draft/conv.prom#6。不管bool值是如何在内存中表示的,编译器的任务是确保上述两件事都是正确的。请记住,C++是在抽象机器上指定的,您的程序只需要在抽象机器上执行。
如果布尔类型的值在内存中被意外地修改为更大的值,会发生什么情况?
未定义的行为。见其中之一:
发布于 2020-01-22 15:57:30
(回答C.)
但是哪个单元或宏决定它只能存储0或1?
在典型的C实现中,编译器实现了这一点。编译器决定(或设计)在操作_Bool值时使用哪些指令。它可以使用一个根据字节是零还是非零来设置条件代码的指令来测试一个_Bool,也可以用一个根据低位(例如)是零还是非零来设置条件代码的指令来测试它。C标准并没有对此提出任何要求。每个C实现都可以自由选择自己的实现。
如果布尔类型的值在内存中被意外地修改为更大的值,会发生什么情况?
这取决于C实现。如果实现测试的是零或非零,则可以将更大的值视为1。如果实现使用该值,则可以根据其低位来处理更大的值。如果实现根据具体情况使用不同的指令,则更大的价值可能在不同的情况下表现得不同。一个更大的价值也可能导致结果,否则将是荒谬的。例如,考虑到int x = 4;和一些通过写入内存而不适当地修改的_Bool y,int z = x + y;可能将z设置为10,尽管如果y是正确的_Bool,则只有4或5是可能的。当您将类型的表示修改为表示由实现定义的适当值的位以外的东西时,生成的行为不是由C标准定义的,通常也不是由C实现定义的。
给布尔类型分配一个更大的值甚至是可能的和允许的吗?
不,赋值将右操作数转换为赋值表达式的类型(这是左操作数的类型,但作为值而不是lvalue除外)。
https://stackoverflow.com/questions/59863467
复制相似问题