什么是静态断言?
静态断言是一种在编译代码时检查条件是否为真的方法。如果不是,则要求编译器发出错误消息并停止编译过程。需要检查的条件是一个常量表达式。
- 执行编译时断言检查
- 句法:
static_assert( constant_expression, string_literal );
在C++ 11标准之前如何进行静态断言?
在C++ 11标准之前,产生编译时错误消息的主要方法是通过#error指令,该指令使实现产生一条诊断消息,其中包括其后的消息。例如:
// Static assertion using #error directive
#include
using namespace std;
#if !defined(__geeksforgeeks)
#error "Geeksforgeeks hasn't been defined yet".
#endif
int main()
{
return 0;
}
错误:尚未定义Geeksforgeeks。
#error指令有什么问题?
#error指令可以很好地完成简单的任务。但是,当需要为复杂的任务(例如,使用sizeof运算符检查数据类型的大小)进行编译时声明时,该方法将失败。这是因为诸如“ sizeof”之类的标记要等到预处理翻译阶段之后才转换为源标记,此时您不能再使用预处理指令。
从C++ 11标准开始,如何进行静态断言?
C++ 11标准引入了一个名为static_assert()的功能,该功能可用于在编译时测试软件断言。
语法:
static_assert( constant_expression, string_literal );
Parameters:
constant_expression: An integral constant expression
that can be converted to a Boolean.
string_literal: The error message that is displayed
when the constant_expression parameter is false.
“ constant_expression”参数表示需要在编译期间检查的软件断言(您期望在程序的特定点上为真的条件)。如果条件为true,则static_assert声明无效。如果条件为假,则断言失败,编译器将在string_literal参数中显示消息,并且编译失败并显示错误。但是,重要的是要注意string_literal参数是可选的。
范例:
// CPP code to demonstrate
// static assertion using static_assert
#include
using namespace std;
template
class Vector {
// Compile time assertion to check if
// the size of the vector is greater than
// 3 or not. If any vector is declared whose
// size is less than 4, the assertion will fail
static_assert(Size > 3, "Vector size is too small!");
T m_values[Size];
};
int main()
{
Vector four; // This will work
Vector two; // This will fail
return 0;
}
输出:
error: static assertion failed: Vector size is too small!
在上面的代码中,我们创建了一个名为vector的模板类,其中我们不想创建一个小于4的矢量。因此,在模板主体内,我们放置了一个static_assert语句来检查该矢量制作的尺寸> 3。如果失败,则声明将失败,并显示错误消息:“向量大小太小”。
这恰恰是在向量类对象“ two”的声明中发生的事情。传递给它的大小为“ 2”,这使要检查的条件失败,因此产生了编译时错误,从而中止了编译过程。
与#error相比,static_assert有什么优势?
- 与#error不同,使用static_assert的断言发生在预处理翻译阶段之后。因此,可以使用static_assert使用sizeof检查数据类型的大小。
// Datatype #include
using namespace std; // No error produced. // The program compiles well because // the size of long datatype is 8 bytes static_assert(sizeof(long) == 8, ode relies on 'long' being exactly 8 bytes"); int main() { return 0; } - 库可以在编译时检测常见的使用错误。
- C++标准库的实现可以检测和诊断常见的使用错误,从而提高可用性。
申报范围
static_assert可以在名称空间范围,类范围以及块范围中使用。每个上述范围的示例如下:
- 命名空间范围:
// CPP program to illustrate // declaring static_assert in namespace scope #include
static_assert(sizeof(void*) == 8, "DTAMDL(*LLP64) is not allowed for this module."); int main() { cout << "Assertion passed. The program didn't produce an error"; return 0; } 输出:
assertion passed. The program didn't produce an error
- 班级范围:
// CPP program to illustrate class scope in // static assertion using static_assert #include
using namespace std; template class Vector { // Compile time assertion to check if // the size of the vector is greater than // 3 or not. If any vector is declared whose // size is less than 4, the assertion will fail static_assert(Size > 3, "Vector size is too small!"); T m_values[Size]; }; int main() { Vector four; // This will work Vector two; // This will fail return 0; } 输出:
error: static assertion failed: Vector size is too small!
- 阻止范围:
// CPP program to illustrate // declaring static_assert in block scope template
void f() { static_assert(N >= 0, "length of array a is negative."); T a[N]; } int main() { // assertion fails here // because the length of the array passed // is below 0 f (); return 0; } 输出:
error: static assertion failed: length of array a is negative.
错误的static_assert
在static_assertion中传递的constant_expression必须是有效的表达式。例如,考虑以下代码:
// CPP program to illustrate
// demonstrating an erroneous static_assert declaration
int main()
{
static_assert(1 / 0, "never shows up!");
return 0;
}
输出:
prog.cpp:5:2: error: non-constant condition for static assertion
static_assert(1 / 0, "never shows up!");
^
在上面的代码中,表达式“ 1/0 ”不是有效的常量表达式。因此,在编译时,编译器将发出一条错误消息,指出除数不得为零,而不是在static_assert声明中显示字符串字面量。