compiler-errors - 如何保证const变量不会发生溢出?

标签 compiler-errors rust constants integer-overflow unsigned-integer

我可以描述这种“圆形”六边形网格的尺寸。

circular hex grid

..在编译时仅定义了1个值n:

const GRID_RADIUS: usize = 3;

因此,在编译时,网格中的单元数也是已知的,因为它是(2n+1)^2-n*(n+1)(此处为37)。

但是,以下内容:

const N: usize = 3;
const N_CELLS: usize = ((2 * N + 1) ^ 2) - N * (N + 1);

struct Cell;

struct Grid {
    cells: [Cell; N_CELLS],
}

无法编译:

error: any use of this value will cause an error
 --> src/main.rs:2:34
  |
2 | const N_CELLS: usize = ((2 * N + 1) ^ 2) - N * (N + 1);
  | -----------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
  |                        |
  |                        attempt to subtract with overflow
  |
  = note: `#[deny(const_err)]` on by default

我知道rustc担心减去usize类型可能会导致溢出,但是我可以保证N_CELLS在这种情况下始终为正。

我该如何对此负责并让rustc信任我?

最佳答案

无法保证-常量值是在编译时评估的。如果值因为执行了计算而溢出,则编译器知道

I understand that rustc worries that subtracting usize types may result in overflow, but I can guarantee that N_CELLS will always be positive in this case.

How can I take responsibility for this and have rustc trust me?


您不能保证这一点(并且编译器不应信任您),因为您是不正确的^表示XOR,而不是“至”的力量。编译器执行了您的代码,并从字面上减去了零,从而触发了错误。这不是假设的:
((2 * n) ^ 2) = 4
n * (n + 1) = 12
4 - 12 = -8
fn main() {
    let n: usize = 3;
    let n_cells: usize = ((2 * n) ^ 2) - n * (n + 1);
}
thread 'main' panicked at 'attempt to subtract with overflow', src/main.rs:3:26
实际上,Rust的thanks to this question现在显示了导致溢出的值,希望可以使原始错误更清晰:
 --> src/lib.rs:2:24
  |
2 | const N_CELLS: usize = ((2 * N + 1) ^ 2) - N * (N + 1);
  | -----------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
  |                        |
  |                        attempt to compute `5_usize - 12_usize` which would overflow
  |
  = note: `#[deny(const_err)]` on by default
也可以看看:
  • How to raise a number to a power?

  • 不幸的是,您当前无法在常量中使用pow:
    const N: usize = 3;
    const N_CELLS: usize = ((2 * N + 1).pow(2)) - N * (N + 1);
    
    error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
     --> src/lib.rs:2:24
      |
    2 | const N_CELLS: usize = ((2 * N + 1).pow(2)) - N * (N + 1);
      |                        ^^^^^^^^^^^^^^^^^^^^
    
    您将必须自己扩展乘法:
    const N_CELLS: usize = {
        let a = 2 * N + 1;
        let b = N * (N + 1);
        a * a - b
    };
    

    关于compiler-errors - 如何保证const变量不会发生溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61191434/

    相关文章:

    macros - `:expr` 后跟 `:tt` ,`expr` 片段不允许

    C++:定义简单常量以供使用?

    c++ - ISO C++禁止无类型的 ‘multiset’声明

    c++ - std::swap 怪异与 G++

    rust - 巩固 cargo 依赖

    javascript - 在 ES6 类中声明静态常量?

    c - "const int x = get();"在 C 中合法吗?我们可以在声明时将函数的返回值分配给常量吗?

    c++ - 如何确定 g++ 编译器错误中缺少的文件?

    compiler-errors - 尝试在 Rust v0.13.0 中打印整数时出现编译错误

    rust - 如何打印函数调用时间线?