在stdlib.h和stdio.h下使用strtol()的结果不同

时间:2019-02-06 15:42:36

标签: gcc posix strtol

当试图解析一个太大而不能容纳一个长整数的数字时,strtol()返回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

1 个答案:

答案 0 :(得分:0)

strtol在标头<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的情况下)具有相同的缺少标题问题。为了产生预期的输出,必须包含LONG_MAX标头stdlib.h