diff --git a/src/exotic-sizes.md b/src/exotic-sizes.md index e97dee4..7b7b605 100644 --- a/src/exotic-sizes.md +++ b/src/exotic-sizes.md @@ -25,7 +25,7 @@ struct MySuperSlice { } ``` -如果这样的类型没有方法来构造它,那么它在很大程度上来看是没啥用的。目前,唯一支持的创建自定义 DST 的方法是使你的类型成为泛型,并执行*非固定大小转换(unsizing coercion)*: +不幸的是,如果这样的类型没有方法来构造它,那么它在很大程度上来看是没啥用的。目前,唯一支持的创建自定义 DST 的方法是使你的类型成为泛型,并执行*非固定大小转换(unsizing coercion)*: ```rust struct MySuperSliceable { diff --git a/src/ffi.md b/src/ffi.md index fe572af..dbe8a11 100644 --- a/src/ffi.md +++ b/src/ffi.md @@ -747,13 +747,13 @@ void bar(struct Bar *arg); ```rust #[repr(C)] pub struct Foo { - _data: [u8; 0], + _data: (), _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, } #[repr(C)] pub struct Bar { - _data: [u8; 0], + _data: (), _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, } diff --git a/src/intro.md b/src/intro.md index 3cca950..9fa7a18 100644 --- a/src/intro.md +++ b/src/intro.md @@ -15,7 +15,7 @@ > > 如果大家对于翻译有更好的建议或者想法,欢迎直接 PR~ > -> 目前翻译基于 commit:bc2298865544695c63454fc1f9f98a3dc22e9948,基于时间:2025/01/24 +> 目前翻译基于 commit:336f75835a6c0514852cc65aba9a698b699b13c8,基于时间:2025/02/02。 > > Q:为什么不基于之前已有的中文版进行改进? > diff --git a/src/other-reprs.md b/src/other-reprs.md index 1787f54..904534b 100644 --- a/src/other-reprs.md +++ b/src/other-reprs.md @@ -63,21 +63,21 @@ assert_eq!(16, size_of::>()); 空指针优化针对无字段且拥有`repr(u*)`、`repr(i*)`或`repr(C)`的枚举仍然生效。 -## repr(packed) +## repr(packed), repr(packed(n)) -`repr(packed)`强制 Rust 去掉任何填充,只将类型对齐到一个字节。这可能会改善内存占用,但可能会有其他负面的副作用。 +`repr(packed(n))`(其中 `n` 是 2 的幂)强制该类型的对齐要求**最多**为 `n`。最常见的用法是不显式指定 `n`,此时 `repr(packed)` 等同于 `repr(packed(1))`,它迫使 Rust 去除所有填充,仅将该类型对齐到一个字节。这可能会改善内存占用,但很可能带来其他负面副作用。 -特别是,大多数架构*强烈地*希望数值被对齐。这可能意味着不对齐的加载会受到惩罚(x86),甚至会出现故障(一些 ARM 芯片)。对于简单的情况,如直接加载或存储一个已打包的字段,编译器可能能够用移位和掩码来解决对齐问题。然而,如果你对一个已打包的字段进行引用,编译器就不太可能发出代码来避免无对齐的加载。 +特别是,大多数体系结构**强烈**偏好数据自然对齐。这可能意味着未对齐的加载会受到惩罚(例如在 x86 架构上),甚至可能导致异常(某些 ARM 芯片)。对于直接加载或存储打包字段这类简单情况,编译器可能能够通过位移和掩码来掩盖对齐问题;然而,如果你对一个打包字段取引用,编译器很可能无法生成避免未对齐加载的代码。 -[由于这可能导致未定义的行为][ub loads],我们在 Lint 中已经实现了对应的检查,并且该行为会被认为是错误。 +[由于这可能导致未定义行为][ub loads],相关的 lint 已经被实现,并且将成为一个硬错误。 -`repr(packed)`是不能轻易使用的,除非你有极端的要求,否则不应该使用这个。 +`repr(packed)/repr(packed(n))` 不应轻易使用。除非你有极端的需求,否则不应采用这种方式。 -这个 repr 是对`repr(C)`和`repr(Rust)`的修改。 +这种 repr 是对 `repr(C)` 和 `repr(Rust)` 的一种修饰。如果你希望一个类型是 FFI 兼容的,那么你通常需要显式指定为:`repr(C, packed)`。 ## repr(align(n)) -`repr(align(n))`(其中`n`是 2 的幂)强制类型*至少*按照 n 对齐。 +`repr(align(n))`(其中`n`是 2 的幂)强制类型*至少*按照`n`对齐。 这可以实现一些技巧,比如确保数组中的相邻元素不会彼此共享同一个缓存行(这可能会加快某些类型的并发代码)。