C++ static_assert 编译期断言

2026年7月13日 Crystal-Sky 3 min read C++C++17基础语法static_assert编译期检查

先回顾普通 assert

普通 assert 用于在程序运行时检查条件。

#include <cassert>

int main() {
    int x = 10;
    assert(x > 0);
}

条件为假时,程序会在运行时终止。因此,assert 属于运行期检查。

什么是 static_assert

static_assert 用于在编译阶段检查条件。

static_assert(条件, "错误信息");

例如:

static_assert(sizeof(int) >= 4,
              "int 类型至少需要 4 字节");

条件为假时,程序无法通过编译。

条件必须能在编译期确定

正确:

constexpr int size = 10;
static_assert(size > 0, "size 必须大于 0");

错误:

int size;
std::cin >> size;
static_assert(size > 0, "size 必须大于 0");

第二段中的 size 只有运行后才能确定,因此不能用于 static_assert

C++17 的简化写法

在较早标准中通常需要写错误信息:

static_assert(sizeof(int) >= 4, "int 太小");

从 C++17 开始,可以省略第二个参数:

static_assert(sizeof(int) >= 4);

不过实际开发中,保留错误信息更方便定位问题。

常见用途

检查类型大小

static_assert(sizeof(long long) >= 8,
              "long long 至少需要 8 字节");

检查模板参数

template <typename T>
T add(T a, T b) {
    static_assert(sizeof(T) >= 4,
                  "类型长度不能小于 4 字节");
    return a + b;
}

结合类型特征

#include <type_traits>

template <typename T>
T twice(T value) {
    static_assert(std::is_integral_v<T>,
                  "T 必须是整数类型");
    return value * 2;
}

调用:

twice(10);     // 正确
twice(3.14);   // 编译错误

检查数组长度

template <typename T, std::size_t N>
void process(T (&arr)[N]) {
    static_assert(N >= 5,
                  "数组长度至少为 5");
}

检查配置常量

constexpr int BufferSize = 1024;

static_assert(BufferSize > 0,
              "缓冲区大小必须大于 0");

static_assert((BufferSize & (BufferSize - 1)) == 0,
              "缓冲区大小必须是 2 的幂");

assert 对比

项目assertstatic_assert
检查时间运行时编译时
条件要求普通布尔表达式常量表达式
失败结果程序终止编译失败
是否需要头文件<cassert>不需要
典型用途检查运行数据检查类型和配置

常见错误

使用运行时变量

int x = 10;
static_assert(x > 0, "x 必须大于 0"); // 错误

如果要检查运行时数据,应使用普通判断或 assert

条件和错误信息矛盾

错误:

static_assert(sizeof(int) < 4,
              "int 至少应有 4 字节");

正确:

static_assert(sizeof(int) >= 4,
              "int 至少应有 4 字节");

总结