22 December 2021

C++ 核心指南目录

C++ 核心指南说,能在编译时检查出错误,就不要在运行时检查,这样可以不用编写错误处理代码。代码的可读性会更好、性能会更佳。

以下代码在运行时检查 int 类型的长度是不是小于 32 位:

int bits = 0;         // don't: avoidable code
for (int i = 1; i; i <<= 1)
    ++bits;
if (bits < 32)
    cout << "int too small\n";
cout << bits;
32

因为数值溢出的行为是未定义的,因此以上实现是不可靠的。可以用 static_assert 进行判断:

static_assert(sizeof(int) >= 4);    // do: compile-time check

如果改成 >=8 静态判断就出错了:

static_assert(sizeof(int) >= 8);    // do: compile-time check
C-src-99WMqo.cpp:11:27: error: static assertion failed
   11 | static_assert(sizeof(int) >= 8);    // do: compile-time check
      |               ~~~~~~~~~~~~^~~~

更好的做法是使用 int32_t 类型。

cout << sizeof(int32_t);
4

另一个例子:如果设置第二个参数给 read 函数,一旦参数过大,就会导致数组越界访问了:

void read(int* p, int n);   // read max n integers into *p

int a[100];
read(a, 1000);    // bad, off the end

如果使用了 gsl::span ,编译器就会确定一次能放多少数据到数组了:

void read(gsl::span<int> r); // read into the range of integers r

int a[100];
read(a);        // better: let the compiler figure out the number of elements