#include <iostream>
int main() {
int a[] = { 21, 213, 45 };
static_assert(a[22], "error for a\n");
return (0);
}
我有一个形状类似于int
数组的查找表,我需要在编译时检查是否使用[]
运算符可能导致读取超出范围。
我知道static_assert
基本上需要两件事:
bool
或可转换/等效于bool
现在在g++ 4.8.1
中,initializer_list
应该是C ++ 11中的常量表达式,我不知道有多少次我看到if
构造像这样编写{ {1}};那断言怎么了?
答案 0 :(得分:4)
我认为你可以用一点模板魔法来概括你想要的东西。
template<typename T,int N> constexpr bool bounds_check(T (&array)[N], int i)
{
return i < N;
}
查看实际操作:http://ideone.com/kj51N0
答案 1 :(得分:2)
访问数组边界是未定义的行为。所以,任何事情都可能发生。
静态断言都是关于编译时失败的。在运行时间之前不会捕获:太晚了。
答案 2 :(得分:2)
a[22]
不是常量表达式。此外,它没有范围检查,因为编译器会将对本机数组的访问重写为*(a + 22)
。要获得范围检查,您需要将a
构建为std::array
,而C ++库需要启用范围检查,有些只能在调试模式下进行。
如果你做static_assert(sizeof(a)/sizeof(*a) > 22, "a not large enough")
答案 3 :(得分:1)
我认为你可以使用:
int a[] = { 21, 213, 45 };
static_assert(sizeof(a)/sizeof(a[0]) > 22, "error for a\n");
return (0);
但这是一个非常奇怪的检查。它仅在编译时知道索引(22
)和a
的大小时才有效。
答案 4 :(得分:1)
template<std::size_t Index, typename T, std::size_t N>
T& at( T(&a)[N] ) {
static_assert( Index < N, "Out of bounds" );
return a[Index];
}
template<std::size_t Index, typename T, std::size_t N>
T& at( std::array<T,N>& a ) {
static_assert( Index < N, "Out of bounds" );
return a[Index];
}
template<std::size_t Index, typename T, std::size_t N>
T const& at( std::array<T,N> const& a ) {
static_assert( Index < N, "Out of bounds" );
return a[Index];
}
使用:
int main() {
int a[] = { 21, 213, 45 };
int x = at<22>(a); // fails to compile
return (0);
}