So I have set of interesting C corner cases…
Consult 7.24.1.7 of WG14 N3220, concering “The strtol, strtoll, strtoul, and strtoull functions” and then look at the following:
// C23 // In all of the following assume errno is initially 0 // Unambiguous r = strtoul("0", &endp, 0) r = strtoul("0", &endp, 2) r = strtoul("0", &endp, 16) // -> strcmp(endp, "") == 0, r = 0, errno = 0; r = strtoul("0b0", &endp, 0) r = strtoul("0x0", &endp, 0) r = strtoul("0b0", &endp, 2) r = strtoul("0x0", &endp, 16) // -> strcmp(endp, "") == 0, r = 0, errno = 0; // The following are ambiguous, however. // What is the correct output for each of these? strtoul("0b", &endp, 0) strtoul("0b", &endp, 2) // -> strcmp(endp, "b") == 0, r = 0, errno = 0;, or // -> errno = ERANGE strtoul("0x", &endp, 0) strtoul("0x", &endp, 16) // -> strcmp(endp, "x") == 0, r = 0, errno = 0;, or // -> errno = ERANGENote: in versions of C prior to C23, the following are unambiguous (the language permitting the 0b prefix was added in C23). Depending upon interpretation, in C23 strtoul may reject inputs that were considered acceptible in in previous versions of the standard
strtoul("0b", &endp, 0) strtoul("0b", &endp, 2) // -> strcmp(endp, "b") == 0, r = 0, errno = 0;