#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
#include <errno.h>
int main(void)
{
long v;
char x[64];
errno = 0;
sprintf(x, "%ld\n", LONG_MIN);
v = strtol(x, NULL, 10);
printf("%ld, %d\n", v, errno);
return 0;
}
Most implementations including MSVC and glibc does not set errno to
ERANGE. Are they correct?
DR006 says that inspecting if the value is in the representable range
should be done neglecting the possible sign. According to that
interpretation, the value without the sign, 2147483648 is not within
the range [-2147483648, 2147483647], so is strtol required to return
LONG_MIN (according to the sign) and set errno properly? Or because
the interpretation given in DR006 applies only to strtoul, is strtol
still required not to set errno?
Thanks in advance.
--
Jun, Woong (woong at icu.ac.kr)
Samsung Electronics Co., Ltd.
``All opinions expressed are mine, and do not represent
the official opinions of any organization.''
DR006 is irrelevant. It was a defect report against the C90 standard,
dated December 10, 1992. See the description of strtol in C99
7.20.1.4.
--
Keith Thompson (The_Other_Keith) <ks...@mib.org>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
MSVC isn't a C99 compiler and gcc is part of a C99 compiler. As such,
how is the description in C99 more relevant to him?
--
Randy Howard (2reply remove FOOBAR)
"The power of accurate observation is called cynicism by those
who have not got it." - George Bernard Shaw
The only differences I can find between C90 and C99 in this regard
are from integrating strto* (integral string conversion) functions
into one subsection in C99 while C90 specified unsigned and signed
conversion functions separately.
With the essentailly identical wording, I don't see why the
authoritative interpretation of the committee given in DR006 is not
allowed to apply to C99. A different intent should be conveyed by
a different wording, shouldn't it?
Hmm. I may have been too hasty.
My point was that DR006 is a defect report against an officially
obsolete standard (though of course the C90 standard is still in wide
use in the real world). If the wording in the response to DR006 has
been incorporated into the C99 standard (I confess I didn't compare it
closely), then it might make more sense, at least in comp.std.c, to
ask about the wording in the C99 standard without reference to C90 or
DR006.
On the other hand, if your real question is about the requirements of
the C90 standard as modified by DR006, that's a perfectly reasonable
question, and I withdraw my implication that it isn't. You just might
have better results here asking about the C99 standard.
When I have more time I'll take a closer look at this myself, and post
if I have anything useful to add.
Yes.
> DR006 says that inspecting if the value is in the representable range
> should be done neglecting the possible sign.
That's becuase DR006 was asking specifically about strtoul, not strtol.
The crux of DR006 was whether negative values should be considered out
of range or whether normal unsigned arithmetic wrap-around should occur
and, if so, does that make the allowable range unlimited. The intent is
that wrap-around does occur for the unsigned functions, but the
allowable range is limited to [-UMAX, UMAX]. For the signed functions,
the allowable range is [MIN, MAX]. (Where MIN, MAX, and UMAX are the
appropriate values for the return type of the function.)
-Larry Jones
Wheeee. -- Calvin
On Tue, 19 Feb 2008 11:30:47 -0500, lawrence.jones wrote:
> Jun Woong <wo...@icu.ac.kr> wrote [re. converting LONG_MIN with strtol):
>> Most implementations including MSVC and glibc does not set errno to
>> ERANGE. Are they correct?
>
> Yes.
Are you sure?
>> DR006 says that inspecting if the value is in the representable range
>> should be done neglecting the possible sign.
>
> That's becuase DR006 was asking specifically about strtoul, not strtol.
Here's what C99 specifies for strtol (7.20.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."
If the sequence of characters starting with the first digit is
"2147483648", it is not within long's range (and by the rules of 6.4.4.1,
would have a different type -- signed long long in this case).
"If the subject sequence begins with a minus sign, the value resulting
from the conversion is negated (in the return type)."
How can you get a value of type long, so that negating that value
produces -2147483648? It seems to me that strtol is *only* allowed to
return LONG_MIN if either LONG_MIN == -LONG_MAX, or strtol sets ERANGE.
I'm sure that was the intent. I've made a note to address the wording (once
again) to make the intended behavior clear.
-Larry Jones
Yep, we'd probably be dead by now if it wasn't for Twinkies. -- Calvin
Isn't it so that in twos complement representation of a signed 32-bit value
-(-2147483648) == -2147483648?
--
MartinS
You're *assuming* that the value resulting from the conversion before
negation is -2147483648, not 2147483648. Furthermore, negating
-2147483648 is not guaranteed to be the same value by the standard.
I do not see why you should tamper with the type when reading 7.20.1.4p*5*.
For example, how to deal with 127? (which is a int integer constant
according to 6.4.4.1, so is not a long integer constant.)
As I read it, the relevant paragraph is really p8, which says
[#8] The strtol, strtoll, strtoul, and strtoull functions
return the converted value, if any. If no conversion could
be performed, zero is returned. If the correct value is
outside the range of representable values, LONG_MIN,
LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX
is returned (according to the return type and sign of
the value, if any), and the value of the macro ERANGE is
stored in errno.
The words "correct value" are not strictly defined, but it is my
understanding that it would be -2147483648 in this case; and I believe this
value is *not* "outside the range of representable values."
So we need to back up a bit to learn if the text allows for -2147483648 to
be the correct value.
With C90 text, how to deal with the minus was described (in the two
paragraphs matching 7.20.1.4p5) as:
If the subject sequence begins with a minus sign, the value
resulting from the conversion is negated.
Again, there are no reason to discard a result of -2147483648 here.
However, C99 FCD changed (was not present in N794 p.327/329/409/411, but is
in N843 p.296/363; I cannot spot the comment which drove this modification)
it to read:
If the subject sequence begins with a minus sign, the value
resulting from the conversion is negated (in the return type).
Now there is a reference to the type! And it is the targetted type, so it
should apply to -2147483648, _not_ to 2147483648! In fact, it looks like as
this addition was done to _avoid_ dealing with the very type of 2147483648!
By the way, this addition I cannot fully understand when it comes to
{str,wcs}tou{l,ll}.
Antoine
The reason for the change was to try to address the confusion
represented in DR 006 as to what strtoul("-1", NULL, 0) is supposed to
do: return ULONG_MAX or a range error. The new words were supposed to
clarify that the minus sign is to be interpreted as unsigned negation in
that case rather than as an attempt to convert a negative value.
Unfortunately, it appears that that attempt was both less than
successful and also added confusion to the signed cases.
-Larry Jones
From now on, I'm devoting myself to the cultivation of
interpersonal relationships. -- Calvin