编译运行:clang++ -std=c++26 -Wall -Wextra -pthread 测试_第17章_编译与调试.cpp -o t && ./t(需先 cd 测试/)
// 第17-18章测试:编译/调试技巧 + 速查表验证
// 本测试包含两类内容:
// 1. 代码层面的速查验证(类型、常量、函数指针、内联函数)
// 2. 编译技巧演示(需在命令行执行额外命令,见文件底部注释)
#include <print>
#include <string>
#include <type_traits>
#include <vector>
int failures = 0;
#define CHECK(expr) \
do { \
if (!(expr)) { \
++failures; \
std::println("FAIL 第{}行: {}", __LINE__, #expr); \
} \
} while (0)
// A.4 头文件守卫演示(本文件自身单次包含,无法演示多文件,
// 这里用一个模拟宏验证模式本身)
#ifndef TEST_GUARD_DEMO
#define TEST_GUARD_DEMO
inline int guard_value() { return 42; }
#endif
// A.3 函数指针
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
// 18 B.5 常识验证
struct HasDefault {
int x = 0;
std::string s = "默认";
};
int main() {
// B.2 类型检查
static_assert(sizeof(int) == 4);
static_assert(std::is_integral_v<long long>);
static_assert(std::is_floating_point_v<double>);
static_assert(std::is_same_v<std::string, std::basic_string<char>>);
// 头文件守卫
CHECK(guard_value() == 42);
// 函数指针(A.3 调试/回调基础)
int (*fn)(int, int) = add;
CHECK(fn(2, 3) == 5);
fn = sub;
CHECK(fn(2, 3) == -1);
std::vector<int (*)(int, int)> fns{add, sub};
CHECK(fns[0](10, 4) == 14 && fns[1](10, 4) == 6);
// B.5 常见坑自查
// 坑1:整数除法
CHECK(7 / 2 == 3);
// 坑4:赋值 vs 比较
int a = 5;
bool is5 = (a == 5);
CHECK(is5);
// 坑9:引用捕获 lambda 生命周期(此处立即调用是安全的)
int n = 10;
auto f = [&n] { return n; };
CHECK(f() == 10);
// 默认成员初始化器
HasDefault hd;
CHECK(hd.x == 0 && hd.s == "默认");
// 数字化分隔符
long big = 1'000'000;
CHECK(big == 1000000);
if (failures == 0) std::println("全部通过");
return failures;
}
/*
命令行编译演示(对应附录 A):
cd "C++中文教程/测试"
clang++ -std=c++26 -Wall -Wextra 测试_第17章_编译与调试.cpp -o t17
clang++ -std=c++26 -O2 测试_第17章_编译与调试.cpp -o t17_opt # 优化版
clang++ -std=c++26 -g 测试_第17章_编译与调试.cpp -o t17_dbg # 调试版
./t17
多文件编译(附录 A.5):
clang++ a.cpp b.cpp -o app
警告打开(附录 A.2):
clang++ -std=c++26 -Wall -Wextra -Werror 源文件.cpp -o 程序
(-Werror 把警告当错误,CI 常用)
*/