stdlib.h和stdio.h下使用strtol()的结果不一样
The result of using strtol() under stdlib.h and stdio.h is different
当试图解析一个太大而不适合长的数字时,strtol() returns 0 而不是 LONG_MAX (stdio.h)。如果我没看错 POSIX 规范,它应该是 LONG_MAX。 stdio.h 和 stdlib.h
有区别
#include "stdio.h"
int main(void){
printf("%ld\n", strtol("99999999999999999999999"));
return 0;
} # 0
#include "stdio.h"
//#include "stdlib.h"
int main(void){
char *end[500];
printf("%ld\n", strtol("99999999999999999999999", end, 10));
return 0;
} # 9223372036854775807
strtol
在 header <stdlib.h>
中声明为
long strtol( const char *restrict str, char **restrict str_end, int base );
// ^^^^^^^^ ^^^^^^^^ since C99
在第一个发布的片段中,不包含 <stdlib.h>
并且函数是用一个参数调用的,因此,如果用 -Wall -Wextra -std=gnu11
编译,gcc 会产生以下解释输出 0 之前的警告:
prog.c: In function 'main':
prog.c:5:21: warning: implicit declaration of function 'strtol' [-Wimplicit-function-declaration]
printf("%ld\n", strtol("99999999999999999999999"));
^~~~~~
prog.c:5:15: warning: format '%ld' expects argument of type 'long int', but argument 2 has type 'int' [-Wformat=]
printf("%ld\n", strtol("99999999999999999999999"));
~~^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%d
这意味着根本没有调用库函数并调用了一个隐式声明的同名函数,返回并打印了值为 0 的 int
(格式说明符错误,即本身未定义的行为)。
请注意,相同的代码无法使用 clang 编译,报告如下:
prog.c:4:21: warning: implicitly declaring library function 'strtol' with type 'long (const char *, char **, int)' [-Wimplicit-function-declaration]
printf("%ld\n", strtol("99999999999999999999999"));
^
prog.c:4:21: note: include the header <stdlib.h> or explicitly provide a declaration for 'strtol'
prog.c:4:53: error: too few arguments to function call, expected 3, have 1
printf("%ld\n", strtol("99999999999999999999999"));
~~~~~~ ^
1 warning and 1 error generated.
在第二个片段中,strtol
使用正确数量的参数调用,但是,如发布的那样(#include
被注释掉),同样存在缺少 header 的问题.要产生预期的输出,必须包含 LONG_MAX、header stdlib.h
。
当试图解析一个太大而不适合长的数字时,strtol() returns 0 而不是 LONG_MAX (stdio.h)。如果我没看错 POSIX 规范,它应该是 LONG_MAX。 stdio.h 和 stdlib.h
有区别#include "stdio.h"
int main(void){
printf("%ld\n", strtol("99999999999999999999999"));
return 0;
} # 0
#include "stdio.h"
//#include "stdlib.h"
int main(void){
char *end[500];
printf("%ld\n", strtol("99999999999999999999999", end, 10));
return 0;
} # 9223372036854775807
strtol
在 header <stdlib.h>
中声明为
long strtol( const char *restrict str, char **restrict str_end, int base );
// ^^^^^^^^ ^^^^^^^^ since C99
在第一个发布的片段中,不包含 <stdlib.h>
并且函数是用一个参数调用的,因此,如果用 -Wall -Wextra -std=gnu11
编译,gcc 会产生以下解释输出 0 之前的警告:
prog.c: In function 'main': prog.c:5:21: warning: implicit declaration of function 'strtol' [-Wimplicit-function-declaration] printf("%ld\n", strtol("99999999999999999999999")); ^~~~~~ prog.c:5:15: warning: format '%ld' expects argument of type 'long int', but argument 2 has type 'int' [-Wformat=] printf("%ld\n", strtol("99999999999999999999999")); ~~^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %d
这意味着根本没有调用库函数并调用了一个隐式声明的同名函数,返回并打印了值为 0 的 int
(格式说明符错误,即本身未定义的行为)。
请注意,相同的代码无法使用 clang 编译,报告如下:
prog.c:4:21: warning: implicitly declaring library function 'strtol' with type 'long (const char *, char **, int)' [-Wimplicit-function-declaration] printf("%ld\n", strtol("99999999999999999999999")); ^ prog.c:4:21: note: include the header <stdlib.h> or explicitly provide a declaration for 'strtol' prog.c:4:53: error: too few arguments to function call, expected 3, have 1 printf("%ld\n", strtol("99999999999999999999999")); ~~~~~~ ^ 1 warning and 1 error generated.
在第二个片段中,strtol
使用正确数量的参数调用,但是,如发布的那样(#include
被注释掉),同样存在缺少 header 的问题.要产生预期的输出,必须包含 LONG_MAX、header stdlib.h
。