2017-09-11 48 views
5

Mam następujący kod:GCC narzeka na str nie może być 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; 
} 

gdy próbuje skompilować go z

[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 

Używam gcc wersję:

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

Nie rozumiem ostrzeżenia. Wartość const char * powinna mieć wartość NULL, prawda?

+2

Niezwiązany z twoim problemem, ale twoja funkcja ma poważną wadę ... Spróbuj użyć np. '" 123abc456 "' jako wejście i zobacz, jaki będzie wynik. –

+0

Prawdopodobnie 'gcc' próbuje wstawić tę funkcję i wie, że nie przekazano do niej żadnych NULL argumentów. Ile razy ta funkcja jest używana w kodzie i jakie są przykłady jego użycia? – myaut

+1

Wydaje się być fałszywie pozytywnym. Chociaż 'if (str)' jest niedbały w porównaniu do 'if (str! = NULL)', nie ma potrzeby rzucania ostrzeżenia. – Lundin

Odpowiedz

17

atoi to standardowa funkcja biblioteki c. Nagłówek tej standardowej funkcji zawiera atrybut __nonnull, który uruchamia obsługę GCC.

Twoja przesłonięta implementacja nie wykorzystuje tej specjalnej obsługi (przy założeniu, że argument nie jest pusty), a więc ostrzeżenie.

Prawdziwa odpowiedź: nie używaj ponownie nazwy funkcji z funkcji z biblioteki standardowej.

+1

Nie mogę odtworzyć problemu z OP gcc 6.1.2, ale bardzo dobra odpowiedź (gratulacje za 10k)! –

+0

Tak samo, nie mogę tego odtworzyć, nawet jeśli dołączam stdlib.h. – Lundin

+0

Mogę odtworzyć, wklejając kod OP * i * dodając '#include '. To właśnie pociąga za sobą atrybut '__nonnull' dla funkcji glibc. Bez tego nie ma problemu. – Peter