C++11 static_assert
1。assert是动态断言,运行期检查,影响性能,故debug版本检查,release关闭。
2。C++11中引入了static_assert这个关键字,用来做编译期间的断言,因此叫作静态断言。
static_assert(常量表达式,"提示字符串")
注解:如果第一个参数常量表达式的值为false,会产生一条编译错误。错误位置就是该static_assert语句所在行,第二个参数就是错误提示字符串。
[1]使用范围:static_assert可以用在全局作用域中,命名空间中,类作用域中,函数作用域中,几乎可以不受限制的使用。
[2]常量表达式:static_assert的断言表达式的结果必须是在编译时期可以计算的表达式,即必须是常量表达式,示例如下:
//该static_assert用来确保编译仅在32位的平台上进行,不支持64位的平台
//该语句可放在文件的开头处,这样可以尽早检查,以节省失败情况下耗费的编译时间
static_assert(sizeof(int) == 4, "64-bit code generation is not supported.");
如果读者使用了变量,则会导致错误。示例如下:
int positive(const int n)
{
static_assert(n > 0, "value must > 0");
return 0;
}
n作为一个变量,在编译期根本无法确定值(无能为力),估属于应用错误范畴。
[3]模板参数:编译器在遇到一个static_assert语句时,通常立刻将其第一个参数作为常量表达式进行演算。
但如果该常量表达式依赖于某些模板参数,则延迟到模板实例化时再进行演算,这就让检查模板参数也成为了可能。
示例如下:
1 #include <cassert>
2 #include <cstring>
3 using namespace std;
4
5 template <typename T, typename U> int bit_copy(T& a, U& b)
6 {
7 assert(sizeof(b) == sizeof(a));
8 //static_assert(sizeof(b) == sizeof(a), "template parameter size no equal!");
9 memcpy(&a, &b, sizeof(b));
10 };
11
12 int main()
13 {
14 int varA = 0x2468;
15 double varB;
16 bit_copy(varA, varB);
17 getchar();
18 return 0;
19 }
[4]性能方面:由于static_assert是编译期间断言,不生成目标代码,因此static_assert不会造成任何运行期性能损失。
leveldb的代码用到了大量的assert and static_assert.
// We first attempt to print into a stack-allocated buffer. If this attempt // fails, we make a second attempt with a dynamically allocated buffer. constexpr const int kStackBufferSize = 512; char stack_buffer[kStackBufferSize]; static_assert(sizeof(stack_buffer) == static_cast<size_t>(kStackBufferSize), "sizeof(char) is expected to be 1 in C++");
1 assert(buffer_offset <= 28 + kMaxThreadIdSize); 2 static_assert(28 + kMaxThreadIdSize < kStackBufferSize, 3 "stack-allocated buffer may not fit the message header"); 4 assert(buffer_offset < buffer_size);