Skip to content

Commit

Permalink
跟随上游 PR #445 更新
Browse files Browse the repository at this point in the history
  • Loading branch information
PureWhiteWu committed Aug 12, 2024
1 parent a36a9b8 commit dff18a5
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 9 deletions.
6 changes: 2 additions & 4 deletions src/exotic-sizes.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ enum Void {} // 没有变体的类型 = 空类型

原则上,Rust 可以基于这个事实做一些有趣的分析和优化,例如,`Result<T, Void>`只表示为`T`,因为`Err`的情况实际上并不存在(严格来说,这只是一种优化,并不保证,所以例如将一个转化为另一个仍然是 UB)。

下面的例子*本来应该*可以编译的:
下面的例子是可以编译的:

```rust,compile_fail
```rust
enum Void {}

let res: Result<u32, Void> = Ok(0);
Expand All @@ -99,8 +99,6 @@ let res: Result<u32, Void> = Ok(0);
let Ok(num) = res;
```

但现在还不让这么玩儿。

关于空类型的最后一个微妙的细节是,构造一个指向它们的原始指针实际上是有效的,但对它们的解引用是未定义行为,因为那是没有意义的。

我们建议不要用`*const Void`来模拟 C 的`void*`类型。很多人之前这样做,但很快就遇到了麻烦,因为 Rust 没有任何安全防护措施来防止用不安全的代码来实例化空类型,如果你这样做了,就是未定义行为。因为开发者有将原始指针转换为引用的习惯,而构造一个`&Void`**是未定义行为,所以这尤其成问题。
Expand Down
2 changes: 1 addition & 1 deletion src/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
>
> 如果大家对于翻译有更好的建议或者想法,欢迎直接 PR~
>
> 目前翻译基于 commit:0ebdacadbda8ce2cd8fbf93985e15af61a7ab895,基于时间:2024/6/5
> 目前翻译基于 commit:6ecf95c5f2bfa0e6314dfe282bf775fd1405f7e9,基于时间:2024/8/12
>
> Q:为什么不基于之前已有的中文版进行改进?
>
Expand Down
6 changes: 3 additions & 3 deletions src/other-reprs.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Rust 允许你指定不同于默认的数据布局策略,并为你提供了[
- 带有字段的枚举在 C 或 C++ 中也没有对应的概念,但是类型的有效桥接[是被定义的][really-tagged]
- 如果`T`是一个[FFI 安全的非空指针类型](ffi.html#空指针优化)`Option<T>`被保证具有与`T`相同的布局和 ABI,因此也是 FFI 安全的。截至目前,这包括`&``&mut`和函数指针,所有这些都不能为空。
-`repr(C)`而言,元组结构和结构一样,因为与结构的唯一区别是字段没有命名。
- `repr(C)`相当于无字段枚举的`repr(u*)`之一(见下一节)。选择的大小是目标平台的 C 应用二进制接口(ABI)的默认枚举大小。请注意,C 语言中的枚举表示法是实现定义的,所以这实际上是一个“最佳猜测”。特别是,当对应的 C 代码在编译时带有某些标志时,这可能是不正确的。
- `repr(C)`相当于无字段枚举的`repr(u*)`之一(见下一节)。选择的大小和符号类型是目标平台的 C 应用二进制接口(ABI)的默认枚举大小与符号类型。请注意,C 语言中的枚举表示法是实现定义的,所以这实际上是一个“最佳猜测”。特别是,当对应的 C 代码在编译时带有某些标志时,这可能是不正确的。
- 带有`repr(C)``repr(u*)`的无字段枚举仍然不能在没有相应变量的情况下设置为整数值,尽管这在 C 或 C++ 中是允许的行为。如果(不安全地)构造一个枚举的实例,但不与它的一个变体相匹配,这是未定义的行为(这使得详尽的匹配可以继续被编写和编译为正常行为)。

## repr(transparent)
Expand All @@ -34,9 +34,9 @@ Rust 允许你指定不同于默认的数据布局策略,并为你提供了[

## repr(u*), repr(i*)

这些指定了使无字段枚举的大小。如果判别符超过了它可以容纳的整数,就会产生一个编译时错误。你可以通过将溢出的元素明确设置为 0 来手动要求 Rust 允许这样做。
这些指定了使无字段枚举的大小和符号类型。如果判别符超过了它可以容纳的整数,就会产生一个编译时错误。你可以通过将溢出的元素明确设置为 0 来手动要求 Rust 允许这样做。

术语“无字段枚举”仅意味着该枚举在其任何变体中都没有数据。没有`repr(u*)``repr(C)`的无字段枚举仍然是一个 Rust 本地类型,没有稳定的 ABI 表示。添加`repr`会使它在 ABI 上被视为与指定的整数大小完全相同
术语“无字段枚举”仅意味着该枚举在其任何变体中都没有数据。没有`repr(u*)``repr(C)`的无字段枚举仍然是一个 Rust 本地类型,没有稳定的 ABI 表示。添加`repr`会使它在 ABI 上被视为与指定的整数类型大小完全相同

如果枚举有字段,其效果类似于`repr(C)`的效果,因为该类型有一个定义的布局。这使得将枚举传递给 C 代码或者访问该类型的原始表示并直接操作其标记和字段成为可能,详见[RFC][really-tagged]

Expand Down
2 changes: 1 addition & 1 deletion src/what-unsafe-does.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
- 对原始指针进行解引用
- 调用 “Unsafe” 的函数(包括 C 函数、编译器的内建指令和原始分配器。
- 实现 “Unsafe” trait
- 改变静态数据
- 访问或者修改可变的静态变量
- 访问 “union” 的字段

这就是全部了。这些操作被归入 unsafe 的原因是,误用其中的任何一项都会引起可怕的未定义行为。调用“未定义行为”使编译器有充分的权利对你的程序做任何坏事。你绝对_不能_调用“未定义行为”。
Expand Down

0 comments on commit dff18a5

Please sign in to comment.