头文件中直接定义变量错误,应使用extern声明并在一个.cpp中定义;c++17起可用inline变量;编译期常量优先用constexpr或const;避免用宏。

头文件里直接写 int global_var; 是错的
这样会导致每个包含该头文件的 .cpp 文件都定义一份 global_var,链接时出现 multiple definition 错误。C++ 的“一个定义规则”(ODR)不允许同一变量在多个翻译单元中定义。
正确做法是:头文件中用 extern 声明,只在**一个** .cpp 文件中定义。
- 头文件(
globals.h):extern int global_counter; extern const double PI;
- 源文件(
globals.cpp):int global_counter = 0; const double PI = 3.1415926;
inline 变量(C++17 起)可以安全放在头文件里
如果你用的是 C++17 或更新标准,inline 变量允许在头文件中定义且不违反 ODR。编译器保证所有副本合并为一个实例。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 头文件中直接写:
inline int global_flag = 1; inline const std::string app_name = "MyApp";
- 无需在 .cpp 中重复定义,所有包含该头文件的编译单元共享同一变量
- 注意:
inline对非 const 非字面量类型(如std::vector<int></int>)也有效,但初始化必须是常量表达式或带构造函数调用(需确保线程安全)
用 constexpr 或 const 声明常量更简单
如果变量值在编译期确定且不可修改,优先用 constexpr 或 const —— 它们默认有内部链接,可放心放在头文件中。
-
constexpr(推荐用于字面量):constexpr int MAX_RETRY = 3; constexpr auto VERSION = "1.2.0";
-
const(C++11 起对内置类型也隐式 inline):const double GRAVITY = 9.80665;
- 注意:
const std::string不算字面量,不能用constexpr,但const在头文件中仍安全(C++17 前需加inline或改用extern)
避免用宏模拟全局变量
像 #define GLOBAL_X 42 看似简单,但它是纯文本替换,没有类型、无法取地址、调试困难,且容易和宏名冲突。
- 宏不参与作用域检查,可能意外覆盖局部变量名
- 调试器看不到宏定义的“变量”,也无法设置断点或观察其变化
- 现代 C++ 应统一用
constexpr或inline替代
实际项目中,最容易被忽略的是 const 变量的链接属性变化:C++17 之前,const int 在头文件中虽不会报错,但每个 .cpp 都会生成独立副本(浪费空间);C++17 起才真正 inline。如果团队编译器版本混杂,建议显式写 inline const 更稳妥。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










