2017-09-11 52 views
5

我有以下代码:GCC抱怨的STR不能为NULL

int atoi(const char * str) 
{ 
    int ret = 0, i; 
    if (str) { 
      for (i = 0; str[i] != '\0'; i++) 
        if (str[i] >= '0' && str[i] <= '9') 
          ret = ret * 10 + str[i] - '0'; 
    } 
    return ret; 
} 

试图与

[email protected] ~/p/book> make 
gcc -c -o db.o db.c -Wall -Werror -std=c99 -g -DVERSION=\"v0.4\" -Wno- 
unused-variable -Wno-unused-function 
gcc -c -o misc.o misc.c -Wall -Werror -std=c99 -g -DVERSION=\"v0.4\" - 
Wno-unused-variable -Wno-unused-function 
misc.c: In function ‘atoi’: 
misc.c:55:5: error: nonnull argument ‘str’ compared to NULL [-Werror=nonnull-compare] 
    if (str) { 
    ^
cc1: all warnings being treated as errors 
Makefile:54: recipe for target 'misc.o' failed 
make: *** [misc.o] Error 1 

我使用gcc版本编译它时:

[email protected] ~/p/book> gcc --version 
gcc (Debian 6.3.0-18) 6.3.0 20170516 

我不明白这个警告。一个const char *应该能够为NULL,对吗?

+2

与您的问题无关,但您的功能存在严重缺陷...尝试使用例如'“123abc456”作为输入,看看会有什么结果。 –

+0

可能'gcc'试图内联该函数,并知道没有传递给它的NULL参数。这个函数在你的代码中使用了多少次?它的用法是什么? – myaut

+1

似乎是一种误报。虽然'if(str)'与'if(str!= NULL)'相比是马虎的样式,但并不需要为此抛出警告。 – Lundin

回答

17

atoi是c库中的标准函数。该标准函数的标题包含属性__nonnull,该属性触发特殊的gcc处理。

您的重写实现不使用该特殊处理(遵守参数不为null的假设),因此是警告。

真实答案:不要从标准库中的函数中重用函数名称。

+1

我不能用gcc 6.1.2重现OP问题,但是非常好的答案(祝贺10k)! –

+0

同样,即使包含stdlib.h,我也无法重现这一点。 – Lundin

+0

我可以通过粘贴OP的代码*和*添加一个'#include '来复制。这就是拉入glibc函数的'__nonnull'属性。没有这些,没有问题。 – Peter