结合静态断言和断言?
Combining static assert and assert?
我有一个看起来像这样的函数:
int div_round_up(int x, int y) {
/**
* This function only works for positive divisor and non-negative dividend!!
*/
assert(y > 0 && x >= 0);
if (x == 0)
return 0;
return (x - 1) / y + 1;
}
它不适用于 y <= 0
或 x < 0
。这对我来说没问题,我什至可以动态检查正确的值,但我想静态检查,当有人输入错误的值时。如果我将 x 和 y 定义为无符号,它们会悄悄地从负值转换为巨大的正值,这会产生错误的结果,所以我不希望这样。当有人试图像 div_round_up(variable, -7)
那样向它提供负值时,我想让编译失败。我该怎么办?
要在编译时验证数字(static_assert
所做的),必须在编译时知道它。要了解为什么需要这样做,请考虑类似 div_round_up(read_integer_from_file(), read_keyboard_character())
的内容。这样做的明显缺点是您必须 在编译时知道 这些数字。
最简单的方法是使它们成为模板参数,这样您就可以(几乎)保持函数的实现相同:
template<int x, int y>
int div_round_up() {
static_assert(y > 0 && x >= 0, "This function only works for positive divisor and non-negative dividend");
if (x == 0)
return 0;
return (x - 1) / y + 1;
}
可以叫作div_round_up<3, 4>()
和will fail the compilation when the static_assert
fires。
如果您使用的是 gcc 或 clang,您可以包含一个宏
#define div_round_up(a, b) (__builtin_constant_p(b) ? drus(a, b) : drud(a, b))
和两个不同的函数,其中 drus
包含 b 的静态断言,而 drud
不包含。
是的,你可以用一些魔法来做到这一点(一位不知名的俄罗斯代码大师告诉我这个技巧)
#define check2(x) typedef char checkVal[(x)?1:-1];
int main() {
check2(3<4);
check2(5<4);
return 0;
}
但在这种情况下也有一个限制。编译器应该知道这个值的结果。在任何其他情况下都是不可能的(恕我直言)。
我有一个看起来像这样的函数:
int div_round_up(int x, int y) {
/**
* This function only works for positive divisor and non-negative dividend!!
*/
assert(y > 0 && x >= 0);
if (x == 0)
return 0;
return (x - 1) / y + 1;
}
它不适用于 y <= 0
或 x < 0
。这对我来说没问题,我什至可以动态检查正确的值,但我想静态检查,当有人输入错误的值时。如果我将 x 和 y 定义为无符号,它们会悄悄地从负值转换为巨大的正值,这会产生错误的结果,所以我不希望这样。当有人试图像 div_round_up(variable, -7)
那样向它提供负值时,我想让编译失败。我该怎么办?
要在编译时验证数字(static_assert
所做的),必须在编译时知道它。要了解为什么需要这样做,请考虑类似 div_round_up(read_integer_from_file(), read_keyboard_character())
的内容。这样做的明显缺点是您必须 在编译时知道 这些数字。
最简单的方法是使它们成为模板参数,这样您就可以(几乎)保持函数的实现相同:
template<int x, int y>
int div_round_up() {
static_assert(y > 0 && x >= 0, "This function only works for positive divisor and non-negative dividend");
if (x == 0)
return 0;
return (x - 1) / y + 1;
}
可以叫作div_round_up<3, 4>()
和will fail the compilation when the static_assert
fires。
如果您使用的是 gcc 或 clang,您可以包含一个宏
#define div_round_up(a, b) (__builtin_constant_p(b) ? drus(a, b) : drud(a, b))
和两个不同的函数,其中 drus
包含 b 的静态断言,而 drud
不包含。
是的,你可以用一些魔法来做到这一点(一位不知名的俄罗斯代码大师告诉我这个技巧)
#define check2(x) typedef char checkVal[(x)?1:-1];
int main() {
check2(3<4);
check2(5<4);
return 0;
}
但在这种情况下也有一个限制。编译器应该知道这个值的结果。在任何其他情况下都是不可能的(恕我直言)。