(有关相关答案的类似问题,请参阅Mystery with bool data type。)
在调试程序时,我注意到在将未初始化的bool数组打印为整数时出现奇怪的输出。考虑一下这个C程序:
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n = 30;
bool* bools = malloc(n * sizeof(bool)); // Uninitialized memory.
for (int i=0; i<n; ++i)
{
int x = bools[i];
assert(x == 0 || x == 1);
printf("%d ", x);
}
printf("\n");
free(bools);
}
由于未初始化的bool数组,输出随每次运行而变化,当然基于先前的内存内容。我的理解是将一个bool转换为int应该总是产生0或1(参见上面的断言,它总是通过);但是,我经常看到这样的输出:
0 0 0 0 0 0 0 144 0 0 0 0 0 0 0 144 16 0 92 113 255 127 0 0 160 41 222 134 255 127
有人可以解释这个程序如何打印除0和1之外的任何东西吗?
更新:简短的回答是,将未初始化的 bool转换为int可以生成除0和1之外的值。(在我的情况下,bools存储为字节,所以它们的未初始化值可以是[0..255]中的任何值。)此外,上面的断言行似乎已经过优化,这使得这个问题更难以调试。
提供更多上下文:我最初编写的函数用于计算bool数组中的设置位数,例如:
int popcount(const bool* v, int n)
{
int c=0;
for (int i=0; i<n; ++i) c += v[i];
return c;
}
我注意到有时会返回更大的结果,而这似乎是不可能的。问题是bool阵列未初始化。对阵列进行归零可以解决问题,但对于我来说如何将bool转换为int可以产生0或1之外的东西仍然没有意义。
答案 0 :(得分:2)
因为限制布尔读取操作将实际值钳制为0或1是没有意义的。
未定义变量的值可以是适合变量大小的任何值。 bool
通常占用一个字节(因为这是最小的可寻址单元),而在具有8位字节的系统上,它意味着bool
可以存储256个不同的值。这就是为什么你看到的数字从0到255不等。
实现可以自由地假设你不会调用UB,这就是你看到0和1之外的值的原因。在没有UB的代码中,所有bool
都将转换为0或1。
答案 1 :(得分:2)
bool
(_Bool
)对象只能包含值0
或1
。在您的情况下,当您访问malloc
返回的具有不确定值的未初始化内存时,您的程序会调用未定义的行为。
严格遵守的程序只会将_Bool
个对象评估为0
或1
。