Skip to content

修复 bool 相关的示例代码 #80

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions docs/undef.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,25 +247,29 @@ Derived d = static_cast<Derived &>(*bp); // 可以

布尔类型 bool,只有 true 和 false 两种取值。

bool 虽然占据 1 字节(8 位)内存空间,但其中只有一个有效位,也就是最低位
bool 占据 1 字节(8 位)内存空间,其中有效的位只有最低位。这个最低位可以是 0 或 1,但其余 7 位仍然参与 bool 的值表示,而且必须始终保持为 0

只有这个最低位可以是 0 或 1,其余 7 位必须始终保持为 0。

如果其余位中出现了非 0 的位,也就是出现 0 和 1 以外的取值,则是未定义行为。
如果其余位中出现了非 0 的位,也就是出现 0 和 1 以外的取值,则读取该 bool 值或者通过 std::bit_cast 产生这种值是未定义行为。

```cpp
char c = 0;
bool b = *(bool *)&c; // 可以,b = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为什么把原来的代码删除了?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

原来的写法导致 UB。你觉得应该保留吗?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你是说 bool b = *(bool *)&c; 是UB?为什么?据我所知char和任意类型的“类型双关”都是允许的,bool和char当然也是可以“类型双关”的。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你是说 bool b = *(bool *)&c; 是UB?为什么?据我所知char和任意类型的“类型双关”都是允许的,bool和char当然也是可以“类型双关”的。

这里的类型双关是单向的。只能通过 char 泛左值访问 bool 对象,但不能反过来。是否有什么资料导致你认为类型双关是双向的呢?

bool b0;
std::memset(&b0, 1, 0);
if (b0) { /* ... */ } else { /* ... */ } // 可以,b0 == false
auto b1 = std::bit_cast<bool>(char(0)); // 可以,b1 == false
```

```cpp
char c = 1;
bool b = *(bool *)&c; // 可以,b = true
bool b2;
std::memset(&b2, 1, 1);
if (b2) { /* ... */ } else { /* ... */ } // 可以,b2 == true
auto b3 = std::bit_cast<bool>(char(1)); // 可以,b3 == true
```

```cpp
char c = 2;
bool b = *(bool *)&c; // 未定义行为
bool b4;
std::memset(&b4, 1, 2);
if (b4) { /* ... */ } else { /* ... */ } // 未定义行为
auto b5 = std::bit_cast<bool>(char(2)); // 未定义行为
```

## 算数类
Expand Down