| Deutsch English Français Italiano |
|
<87ikxztbb6.fsf@nosuchdomain.example.com> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Keith Thompson <Keith.S.Thompson+u@gmail.com>
Newsgroups: comp.lang.c
Subject: Re: The difference between strtol() and strtoul() ?
Date: Sun, 23 Jun 2024 17:49:01 -0700
Organization: None to speak of
Lines: 71
Message-ID: <87ikxztbb6.fsf@nosuchdomain.example.com>
References: <v51d1l$2fklr$1@news.xmission.com>
<v540t9$2gsdu$1@news.xmission.com> <20240621182839.00000dc4@yahoo.com>
<20240621185314.00004fda@yahoo.com> <87o77uqktg.fsf@bsb.me.uk>
<20240623121952.00005fa9@yahoo.com> <87r0cnq46s.fsf@bsb.me.uk>
<20240623153219.000009b0@yahoo.com> <87jzifpth6.fsf@bsb.me.uk>
<864j9jh77d.fsf@linuxsc.com> <87r0cntga9.fsf@nosuchdomain.example.com>
<87o77rnrt2.fsf@bsb.me.uk>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Date: Mon, 24 Jun 2024 02:49:05 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="0a690d6294358a2c4bce5879f14e083a";
logging-data="630828"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+WpJCRc8Eo0GtHe/KT/upQ"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux)
Cancel-Lock: sha1:WNwKhzImSLgv4vU5ks3vEHYCLZ8=
sha1:6OzF2/DVWlUjS4w4OaX7inzVK3U=
Bytes: 4657
Ben Bacarisse <ben@bsb.me.uk> writes:
> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>> Ben Bacarisse <ben@bsb.me.uk> writes:
>>> [range questions for strtol(), etc]
>>>
>>>> I think there /is/ something problematic with the wording about the
>>>> negation. It happens "in the return type" but how can
>>>> 9223372036854775808 be negated in the type long long int? OK, the
>>>> negated value can be /represented/ in the type long long int but that's
>>>> not quite the same thing. On the othee hand, for the unsigned return
>>>> types, the negation "in the return type" is what produces ULONG_MAX for
>>>> "-1" when the negated value, -1, can't be /represented/ in the return
>>>> type. It's a case where, over the years, I've just got used to what's
>>>> happening.
>>>
>>> I understand what these functions do, but their specification in the
>>> C standard is a little off. To my way of thinking the impact is
>>> minimal, but the specified behavior is either unequivocally wrong or
>>> there are some cases that give rise to undefined behavior.
>>
>> Can you give an example where the specified behavior causes undefined
>> behavior?
>
> I don't want to pre-empt Tim's answer, but the wording that bothers me
> is
>
> "If the subject sequence begins with a minus sign, the value resulting
> from the conversion is negated (in the return type)."
>
> For strtoll("-9223372036854775808", 0, 0) the value resulting from the
> conversion is 9223372036854775808 which can not even be represented in
> the return type, so how can it be negated "in the return type"?
Understanding the significance of your example requires recognizing
that number, which I didn't immediately.
I'll assume in the following that long long and intmax_t are 64 bits,
2's-complement, no padding bits.
9223372036854775808 is 2**63, and is mathematically equal to
LLONG_MAX+1.
-9223372036854775808 is mathematically equal to LLONG_MIN,
but the behavior of the strtoll() call is specified in
terms of computing 9223372036854775808 (outside the range of
long long) and then negating it. It's obvious (I think) that
strtoll("-9223372036854775808", 0, 0) *should* return LLONG_MIN and
not set errno to ERANGE (which it does in every implementation I've
tried), but the way the standard describes it involves a semantically
impossible operation.
-9223372036854775808 is the mathematical value of LLONG_MIN, but
it's not a valid C expression (so <limits.h> typically has to use
some workaround like (-LLONG_MAX-1)) -- but we expect strtoll to
handle it in the obvious way.
Beyond this example, the wording is also problematic
for out-of-range values with a leading '-' sign, such as
strtoll("-9999999999999999999", 0, 0). The result should be
LLONG_MIN with errno==ERANGE, but again the standard says "the value
resulting from the conversion is negated (in the return type)",
which is not actually possible. The same applies to strtoull().
It's not surprising that implementers have inferred the intent
even if the standard doesn't precisely state it. Still, I'd like
to see the wording made more precise.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */