交付软件给客户却是很多问题,一些问题解决就可以了。但有些问题却是一时出现,一时不出现,十分令人恼火,程序猿是超人也难以应付。本文以编译警告为引入点述说在开发过程中的匪夷所思的问题。引以为鉴,重视警告的影响。
1.未引用形参
1 | warning: unused variable 'value'. |
致命行为:
用错变量导致程序得不到正确结果。
1
2
3
4double sum(double a, double b)
{
return a;
}变量未使用造成内存泄漏。
1
2
3...
Car car = new Car();
...
建议:
- 避免这种行为,但这种情况下大多数出现在作为函数参数。但你要明确的是尽管作为扩展(以后使用)用的函数参数,是否应该考虑下本身设计的问题。
2.可能丢失数据
1 | warning: implicit conversion turns floating-point number into integer: 'double' to 'int'. |
致命行为:
- 丢失精度,类似于蝴蝶效应,小小的精度却会引起巨大的误差。
- 整型转换枚举导致枚举变量成不确定值。
1
2enum Fruits { Apple, Orange, Banana};
Fruits fruits = (Fruits)5; // fruits成不确定值,值取决于编译器。
建议:
- 强制转换导致丢失数据,应该避免此行为。
- 但有些情况下却不会,例如整型转换浮点型,枚举转整型。它们都是从小范围转换到大范围。
3.初始化变量顺序不正确
1 | warning: field 'j' will be initialized after field 'i'. |
致命行为:
- 导致变量值偏离。
1
2
3
4
5
6
7
8
9
10
11class Car
{
public:
Car () : j(i + 2), i(1) // 由于j先于i初始化,导致j变量的预期结果却不是3。
{
}
private:
int i;
int j;
};
建议:
- 注意:该行为多出现于类和结构体(C++)的构造函数中。
- 变量之间存在依赖关系容易造成难以想象的bug,就好比怎么有时运行可以,有时却不可以的问题。
4.if语句有空语句
1 | warning: if statement has empty body. |
致命行为:
- 有时运行正常,有时运行异常(非常令人恼火的bug)。
1
2if (enable); // 由于";"语句的存在导致value的值一直不会刷新。
value = sum(i, j);
建议:
- 必须修正!
5.可能除0
1 | warning: division by zero is undefined. |
致命行为:
- 导致程序异常退出。
1
value = i / j; // 由于j变量可能为0值,严重会导致程序异常退出。
建议:
- 先判断变量是否为不为0,再做运算。
6.变量使用前未初始化
1 | warning: variable 'value' is uninitialized when used here. |
致命行为:
- 过于相信直觉,以为
value
默认为0。导致难以想象的bug。1
2
3int value;
if (value == 0) // 由于变量未确定初始值,则值不确定会导致判断有时会不进入。
enable = true;
建议:
- 养成给变量初始化的好习惯。
7.使用=
作为比较
1 | warning: using the result of an assignment as a condition without parentheses. |
致命行为:
- 唔使用导致判断一直生效或失效的行为。
1
2
3
4
5if (i = 1) // 一直生效
enable = true;
if (i = 0) // 一直失效
enable = true;
最后
- 这些编译警告只是冰山一角,有些能正常运行,有些却是致命错误。引以为鉴!
- 如读者也有些值得注意的警告可以在公众号留言分享给大家。