Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.fsmpi.rwth-aachen.de!newsfeed.straub-nv.de!eternal-september.org!feeder.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Code for strtol/strtoul Date: Sat, 21 Mar 2015 15:54:55 -0700 Organization: None to speak of Lines: 54 Message-ID: <87sicyufk0.fsf@kst-u.example.com> References: <878ueqvylj.fsf@kst-u.example.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: mx02.eternal-september.org; posting-host="c77ff4d35e33d1c939d3461ebde8dd0d"; logging-data="32571"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+g97UElLtgqm2nIQLBTZrf" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Cancel-Lock: sha1:gdJsxrP6y4loKc36n0wL49f6Bw0= sha1:+LhJol31GZ/6uWOy8N8xjJN7t08= Xref: csiph.com comp.lang.c:58616 Keith Thompson writes: [...] > Yes, a leading + or - sign is permitted. "If the subject sequence > begins with a minus sign, the value resulting from the conversion is > negated (in the return type)." Negation is well defined for unsigned > types. [...] But that raises an interesting question. Assume LONG_MAX==2147483647, LONG_MIN==-LONG_MIN-1 (32-bit 2's-complement). How does strtol("-2147483648", NULL, 0) work? The obviously useful behavior is for it to return LONG_MIN and *not* set errno. But look at the description in the standard (N1570 7.22.1.4p5): If the subject sequence has the expected form and the value of base is zero, the sequence of characters starting with the first digit is interpreted as an integer constant according to the rules of 6.4.4.1. So far so good; "2147483648" has the form of an integer constant. If the subject sequence begins with a minus sign, the value resulting from the conversion is negated (in the return type). So *first* the value of the digit sequence is determined, and *then* that value is negated if the string began with a minus sign. But 2147483648 is outside the range of the return type. There is no value of type long that you can negate and yield -2147483648, so there's nothing that be "negated (in the return type)" to yield that value. In the glibc implementation, strtol("2147483648", NULL, 0) returns LONG_MAX and sets errno to ERANGE (which is the correct behavior). But strtol("-2147483648", NULL, 0) returns -2147483648 and doesn't set errno -- which is perfectly sensible and useful behavior, and probably what was intended. But I don't see how it's consistent with the requirements stated in the standard. There *should* be a special case for LONG_MAX and LLONG_MAX for strtoul, strtoll, but it's not stated. Is this a bug in the standard, or am I missing something? -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"