写完一段 C 代码,敲下 gcc main.c -o main,终端里突然冒出一行:main.c:12:5: warning: unused variable 'tmp' [-Wunused-variable]。你扫了一眼,没当回事,./main 运行也正常,就关了终端。
警告不是错误,但也不是空气
编译器报错(error)会直接中断生成可执行文件,而警告(warning)只是打个招呼,程序照样能编译通过、跑起来。正因如此,很多人把它当“温馨提示”——关掉、忽略、右上角叉掉。但警告其实是编译器在说:“我看出点不对劲,虽然我能硬着头皮往下走,但你最好看看。”
常见警告,其实都在提醒这些事
比如变量定义了却没用:
int main() {
int tmp = 42;
return 0;
}又比如函数参数声明了,但压根没碰它:
void log_message(char* msg, int level) {
printf("Received message\n"); // level 没用上
}再比如整数除法截断丢失精度:
int a = 5;
int b = 2;
float result = a / b; // 实际是 5/2=2,再转成 float 2.0,不是 2.5这些都不是语法错误,C 标准允许这么写,但它们往往暴露逻辑疏漏、潜在 bug 或未来维护隐患。
警告级别可以调,但别关光
像 GCC 默认只开基础警告,加 -Wall 才打开常用警告组,-Wextra 再补一批更细致的。有些团队甚至用 -Werror 把警告当错误处理,不解决就不让过 CI。这不是矫情,是把问题拦在本地,而不是等上线后半夜被用户截图反馈“点按钮没反应”。
顺手试试:gcc -Wall -Wextra main.c,说不定你那“一直好好的”项目里,藏着七八条被忽视的警告。
别信“运行没问题”,信编译器的眼睛
人看代码容易跳读、凭经验脑补;编译器不带感情,逐字扫描语义和上下文。它提醒你“这个指针可能为空但没检查”,可能就是下次 Segmentation fault 的伏笔;它说“格式字符串和参数类型不匹配”,很可能某天输入一串长字符串就溢出栈了。警告不是打扰,是免费的静态审查员,蹲在你每次编译时默默盯梢。