如何保证const变量不会溢出?
How can I guarantee that overflow will not occur in const variables?
我可以描述这个 "circular" 六边形网格的维度..
.. 在编译时只定义了 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?
你不能保证这一点(编译器不应该信任你)因为你是不正确的。 ^
表示异或,而不是“的幂”。编译器执行了您的代码并从字面上减去零以下,从而触发了错误。这不是假设:
((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
事实上,thanks to this question,Rust 现在显示导致溢出的值,希望能使原来的错误更清楚:
--> 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
另请参阅:
很遗憾,您目前不能在常量中使用 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
};
我可以描述这个 "circular" 六边形网格的维度..
.. 在编译时只定义了 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 subtractingusize
types may result in overflow, but I can guarantee thatN_CELLS
will always be positive in this case.How can I take responsibility for this and have
rustc
trust me?
你不能保证这一点(编译器不应该信任你)因为你是不正确的。 ^
表示异或,而不是“的幂”。编译器执行了您的代码并从字面上减去零以下,从而触发了错误。这不是假设:
((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
事实上,thanks to this question,Rust 现在显示导致溢出的值,希望能使原来的错误更清楚:
--> 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
另请参阅:
很遗憾,您目前不能在常量中使用 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
};