void set_value(int* val) {
double r = 0.0;
if(isRandom) {
double r = this->generateRandomNumber();
*val = r;
上述代码运行后,val的值始终是0而不可能被改成随机值。
VS下有好几个开关:/we6244 /we6246 /we4457 /we4456
(MSDN上还有个 /we2082但实际用的时候提示无效: 命令行 warning D9014: 值“2082”对于“/we”无效;假定为“5999”)。gcc下用-Werror=shadow
6. 函数返回局部变量的地址
VS下的开关:/we4172
。gcc下用-Werror=shadow -Werror=return-local-addr
。
7. 变量没有初始化就使用
函数调用完毕,无法保证用过的栈帧空间后续被如何使用(编译器是否开启优化、栈帧布局结构都有影响),不可侥幸。
VS下的开关:/we4700
。gcc下用-Werror=uninitialized
。
8. printf等语句中的格式串和实参类型不匹配
例如%d匹配到了double,结果肯定不对,应当提前检查出来。
VS下的开关:/we4477
。gcc下用-Werror=format
。
9. 把unsigned int和int类型的两个变量比较
有符号数可能在比较之前被转换为无符号数而导致结果错误。
VS下的开关:/we4018
。gcc下用-Werror=sign-compare
。
10. 把int指针和int相互赋值
虽说可以把指针的值(一个地址)当做一个int(其实是unsigned int)来理解,但考虑这种情况:int a=*p被写成int a=p而引发错误。
VS下的开关:/we4047
。gcc下用-Werror=int-conversion
。
因为上述N条规则是我自行制定的,有些是C++下默认视为错误,有些则是C++下也为警告。因此不妨把CFLAGS和CXXFLAGS都添加这些检查规则。
在开发环境中配置上述CFLAGS
建议基于CMakeLists.txt,现有Visual Studio工程也可配置,具体见文章第一部分“快速配置”。
其他配置方式说明:
.c代码中使用#pragma warning (error: xxxx)
。缺点:只有visual studio工程能用;不能确保所有文件有效
Visual Studio工程属性中配置->配置属性->C/C++->高级->将特定的警告视为错误,填写"xxxx"。缺点:只适合Visual Studio;优点:非CMake生成的VS工程,适合。
gcc编译时指定flags,例如gcc gcc xxx.c -Werror=implicit-function-declaration
CMakeLists.txt中配置说明:set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /weXXXX")
(windows)或set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=xxxx")
。
其中,windows格式中XXXX为警告编号;gcc下xxxx为警告对应的字符串。这种方式个人推荐。
C++编译器默认链接C++标准库,C++标准库包含了math库;C编译器默认链接C标准库,C标准库不包含math库(参考:Why do you have to link the math library in C?)。问题来了:对于gcc,如果纯C代码调用了math函数而没有设定链接选项-lm
,会使用gcc的built-in函数;同样的代码,VS2017并没有内置math库的函数,没有链接数学库的秦广下,为什么也能正确运行?
#include <stdio.h>
#include <math.h>
int main() {
double x = -3.3;
double y = fabs(3.3);
printf("fabs(%lf)=%lf\n", x, y);
return 0;
2020-10-15 14:12:58 同事ZYC因为没有#include <stdlib.h>
,导致malloc时出现分配非法地址,查bug查了大半天。包含utils.cmake后快速报错定位问题。
/w, /W0, /W1, /W2, /W3, /W4, /w1, /w2, /w3, /w4, /Wall, /wd, /we, /wo, /Wv, /WX (Warning Level)
How to set compiler options with CMake in Visual Studio 2017
Make one gcc warning an error?
Can I treat a specific warning as an error?
Is there an equivalent of gcc's -Wshadow in visual C++
已释放的栈内存
GCC编译选项
关于gcc内置函数和c隐式函数声明的认识以及一些推测
Why do you have to link the math library in C?
Greatness is never a given, it must be earned.