C或C++中常见的bug来源是
size_t n = // ...
for (unsigned int i = 0; i < n; i++) // ...
字符串
当unsigned int
溢出时,其可以无限循环。
例如,在Linux上,unsigned int
是32位的,而size_t
是64位的,所以如果n = 5000000000
,我们得到一个无限循环。
我如何使用GCC或clang获得关于此的警告?
GCC的-Wall -Wextra
不能做到这一点:
#include <stdint.h>
void f(uint64_t n)
{
for (uint32_t i = 0; i < n; ++i) {
}
}
gcc-13 -std=c17 \
-Wall -Wextra -Wpedantic \
-Warray-bounds -Wconversion \
-fanalyzer \
-c -o 76840686.o 76840686.c
的数据
(no输出)
2条答案
按热度按时间wwodge7n1#
对于C++,你甚至可以做得比编译器警告更好,假设
n
是编译时常量。这也适用于非gcc编译器。但这种逻辑不适用于C代码。这个想法基本上是在变量类型中编码值信息,而不是变量值。
字符串
如果该值不是编译时常量,您仍然可以为整数创建 Package 器模板类型,并重载
<
运算符以与整数值进行比较,将static_assert
s添加到该运算符的主体中。型
请注意,更改比较运算符的操作数之一的类型的必要性既有好处也有缺点:它要求你修改代码,但它也允许你在每个变量的基础上应用检查…
jchrr9hc2#
用于此目的的gcc seem to support
-Warith-conversion
的最新版本:-Warith-conversion
个即使将操作数转换为相同类型不能更改其值,也要对算术运算的隐式转换发出警告。这会影响来自
-Wconversion
、-Wfloat-conversion
和-Wsign-conversion
的警告。字符串
但它不适用于your example。