c - What is the correct behavior of strtol? -
i'm creating wrapper function around strtol()
int16_t
, , ran across problem: how handle input such 0x
? is, valid digit 0
, followed non-digit x
, or invalid because nothing follows 0x
?
tl;dr results: windows rejects 0x
described in latter case, debian sees digit 0
, followed non-digit character x
, explained in former case.
implementations tested1
- windows
- visual c++ 2015 (henceforth msvc)
- mingw-w64 gcc (5.2.0)
- debian
for further comparison purposes, included sscanf()
format specification of " %li"
, supposed act strtol()
base==0
. surprisingly, ended 2 different results.
code:
#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { const char *foo = " 0x"; char *remainder; long n; int base = 0; n = strtol(foo, &remainder, base); printf("strtol(): "); if (*remainder == 'x') printf("ok\n"); else { printf("nomatch\n"); printf(" remaining -- %s\n", remainder); printf(" errno: %s (%d)\n", strerror(errno), errno); } errno = 0; base = sscanf(foo, " %li", &n); printf("sscanf(): "); if (base == 1) printf("ok\n"); else { printf("nomatch\n"); printf(" returned: %s\n", base==0 ? "0" : "eof"); printf(" errno: %s (%d)\n", strerror(errno), errno); } }
debian results:
strtol(): ok sscanf(): ok
windows results:
strtol(): nomatch remaining -- 0x errno: no error (0) sscanf(): nomatch returned: 0 errno: no error (0)
there no error in case, yet results differed. initializing base
16 instead of 0 made no difference @ all, nor did removal of leading blanks in test string.
i expected result got on debian: 0
parsed valid value (whether base
0 or 16), , remainder
set point x
after seeing there no valid hexadecimal values following x
(had there been any, 0x
skipped whether base
0 or 16).
so i'm confused correct behavior in situation. either of these behaviors in violation of c standard? interpretation of relevant sections of standard debian correct, i'm not certain.
1 cygwin exhibited windows behavior in case of strtol()
, debian behavior in case of sscanf()
interested. since behavior of %li
supposed match strtol()
base==0
, considered bug , ignored results.
the specification 7.22.1.4 of c11:
if value of base zero, expected form of subject sequence of integer constant described in 6.4.4.1,
the subject sequence defined longest initial subsequence of input string, starting first non-white-space character, of expected form
as described in 6.4.4.1, 0
integer constant, 0x
not. therefore, subject sequence 0
input case.
so correct behaviour return 0
, , endptr
should left pointing x
.
Comments
Post a Comment