如何断言 `usize` 的大小以放弃对不兼容平台的支持?

问题描述 投票:0回答:1

问题

我刚刚发现我自己写了动态断言,它依赖于常数

usize::MAX

我写道:

  u128::try_from(letters.len())
     .expect("No support for platform with `max pointer value` >= 2**128.")

其中

letters.len()
usize
的实例。

相反,我希望我的代码无法在“指针大小 >= 2**128”的罕见(如果存在)平台上编译。

我已经知道/读过:

我读过类似的问题(由社区建议)。 它展示了断言指针具体大小的方法。
例如。

#[cfg(not(target_pointer_width = "64"))]

我希望我的代码非常灵活。
usize::MAX<=u128::MAX && usize::MIN>=u128::MIN
成为
true
就足够了。

小反射(也许是解决方案)

经过一番思考,我制定了一个解决方案,无论是在我的脑海中还是在当前测试的具有 x64 架构和 Rust 1.60Debian 上,它都工作得很好
代码:

const _:()= assert!(usize::BITS<=u128::BITS);

您知道任何更干净且防边缘情况的解决方案吗?

rust size platform static-assert compiler-directives
1个回答
1
投票

assert!()
还好。
assert!()
自 Rust 1.57.0
起仅在 const 上下文中可用,因此如果您需要支持旧版本,可以使用
static_assertions
crate
。这个想法是将
assert!()
替换为以下常量表达式:

const _: [(); 0 - (!(usize::BITS <= u128::BITS)) as usize] = [];

现在,如果表达式的计算结果为

true
,则其否定计算结果为
false
,并且
false as usize
为零。所以我们声明一个零长度数组,一切都很好。

但是,如果表达式的计算结果为

false
,则其否定为
true
true as usize == 1
0usize - 1usize
溢出 - 这是一个错误。

缺点是它会生成一条非常晦涩的错误消息:

error[E0080]: evaluation of constant value failed
 --> src/lib.rs:1:15
  |
1 | const _: [(); 0 - (!(usize::BITS > u128::BITS)) as usize] = [];
  |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow

(我交换了条件,所以它会是

false
)。

© www.soinside.com 2019 - 2024. All rights reserved.