Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #21907 > unrolled thread
| Started by | Johannes Bauer <dfnsonfsduifb@gmx.de> |
|---|---|
| First post | 2012-06-06 15:55 +0200 |
| Last post | 2012-06-07 17:08 -0400 |
| Articles | 20 on this page of 30 — 9 participants |
Back to article view | Back to comp.lang.c
Signed mod unsigned Johannes Bauer <dfnsonfsduifb@gmx.de> - 2012-06-06 15:55 +0200
Re: Signed mod unsigned James Kuyper <jameskuyper@verizon.net> - 2012-06-06 10:41 -0400
Re: Signed mod unsigned Johannes Bauer <dfnsonfsduifb@gmx.de> - 2012-06-07 12:12 +0200
Re: Signed mod unsigned James Kuyper <jameskuyper@verizon.net> - 2012-06-07 06:44 -0400
Re: Signed mod unsigned Johannes Bauer <dfnsonfsduifb@gmx.de> - 2012-06-07 13:31 +0200
Re: Signed mod unsigned gwowen <gwowen@gmail.com> - 2012-06-06 07:53 -0700
Re: Signed mod unsigned Johannes Bauer <dfnsonfsduifb@gmx.de> - 2012-06-07 12:15 +0200
Re: Signed mod unsigned "BartC" <bc@freeuk.com> - 2012-06-07 12:29 +0100
Re: Signed mod unsigned Johannes Bauer <dfnsonfsduifb@gmx.de> - 2012-06-07 13:43 +0200
Re: Signed mod unsigned Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-07 07:46 -0400
Re: Signed mod unsigned Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-07 20:58 +0100
Re: Signed mod unsigned Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-07 19:58 -0400
Re: Signed mod unsigned Tim Rentsch <txr@alumni.caltech.edu> - 2012-06-08 02:20 -0700
Re: Signed mod unsigned Johannes Bauer <dfnsonfsduifb@gmx.de> - 2012-06-08 11:33 +0200
Re: Signed mod unsigned Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-08 12:30 +0100
Re: Signed mod unsigned Tim Rentsch <txr@alumni.caltech.edu> - 2012-06-08 11:12 -0700
Re: Signed mod unsigned Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-08 20:37 +0100
Re: Signed mod unsigned Keith Thompson <kst-u@mib.org> - 2012-06-08 13:44 -0700
Re: Signed mod unsigned Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-08 22:22 +0100
Re: Signed mod unsigned Johannes Bauer <dfnsonfsduifb@gmx.de> - 2012-06-10 10:56 +0200
Re: Signed mod unsigned Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-10 14:40 +0100
Re: Signed mod unsigned Keith Thompson <kst-u@mib.org> - 2012-06-11 15:49 -0700
Re: Signed mod unsigned Tim Rentsch <txr@alumni.caltech.edu> - 2012-06-24 09:32 -0700
Re: Signed mod unsigned Tim Rentsch <txr@alumni.caltech.edu> - 2012-06-08 11:05 -0700
Re: Signed mod unsigned Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-08 12:06 +0100
Re: Signed mod unsigned Tim Rentsch <txr@alumni.caltech.edu> - 2012-06-08 11:32 -0700
Re: Signed mod unsigned Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2012-06-06 22:15 +0000
Re: Signed mod unsigned James Kuyper <jameskuyper@verizon.net> - 2012-06-06 18:29 -0400
Re: Signed mod unsigned Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2012-06-07 20:44 +0000
Re: Signed mod unsigned James Kuyper <jameskuyper@verizon.net> - 2012-06-07 17:08 -0400
Page 1 of 2 [1] 2 Next page →
| From | Johannes Bauer <dfnsonfsduifb@gmx.de> |
|---|---|
| Date | 2012-06-06 15:55 +0200 |
| Subject | Signed mod unsigned |
| Message-ID | <jqnnfr$96n$1@news.albasani.net> |
Hi group,
today I ran into something I honestly did not expect. Consider this snippet:
#include <stdio.h>
int main() {
int i1, i2;
unsigned int u2;
i1 = -1;
i2 = 30;
u2 = 30;
printf("%d\n", i1 % i2);
printf("%d\n", i1 % u2);
return 0;
}
I expected to find the output "-1 / -1". Instead the result I got was
"-1 / 15". Apparently when getting the remainder of a signed by a
unsigned int, the signed is silently promoted to unsigned in twos
complement and then the operation is performed, i.e.
0xffffffff % 30 == 15
I would have expected at least a warning since I find this highly
unintuitive -- my expectation would be that the unsigned becomes a
(truncated) signed and a warning. Instead gcc does not emit a warning
(-Wall -Wextra) and silently performs above operation.
Is this really in accordance with the C standard or is gcc doing
something weird here?
Best regards,
Joe
--
>> Wo hattest Du das Beben nochmal GENAU vorhergesagt?
> Zumindest nicht öffentlich!
Ah, der neueste und bis heute genialste Streich unsere großen
Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$1@speranza.aioe.org>
[toc] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-06-06 10:41 -0400 |
| Message-ID | <4FCF6C36.300@verizon.net> |
| In reply to | #21907 |
On 06/06/2012 09:55 AM, Johannes Bauer wrote:
> Hi group,
>
> today I ran into something I honestly did not expect. Consider this snippet:
>
> #include <stdio.h>
>
> int main() {
> int i1, i2;
> unsigned int u2;
>
> i1 = -1;
>
> i2 = 30;
> u2 = 30;
>
> printf("%d\n", i1 % i2);
> printf("%d\n", i1 % u2);
> return 0;
> }
>
> I expected to find the output "-1 / -1". Instead the result I got was
> "-1 / 15". Apparently when getting the remainder of a signed by a
> unsigned int, the signed is silently promoted to unsigned in twos
> complement and then the operation is performed, i.e.
>
> 0xffffffff % 30 == 15
>
> I would have expected at least a warning since I find this highly
> unintuitive -- my expectation would be that the unsigned becomes a
> (truncated) signed and a warning. Instead gcc does not emit a warning
> (-Wall -Wextra) and silently performs above operation.
>
> Is this really in accordance with the C standard or is gcc doing
> something weird here?
In most binary expressions (modulus expressions are no exception -
6.5.5p3), the operands are subject to what is called the usual
arithmetic conversions (6.3.1.8) before the operation is performed.
Those conversions include the integer promotions, which leave both
operands unchanged in this case. The relevant rule is that when one
promoted type is unsigned, and the other is signed, if the unsigned type
has an integer conversion rank greater than or equal to that of the
signed type, then the operand of the signed type is converted to the
unsigned type. "unsigned int" is required to have the same integer
conversion rank as "int" (6.3.1.1p1);
So the behavior you describe is not only allowed, but required, by the C
standard. There's some minor details about your description that should
be modified: this is not an example of what the C standard calls a
promotion, and it has nothing to do with 2's complement. The C standard
also allows 1's complement and sign-magnitude representations
(6.2.6.2p2), and the conversion from a signed value to an unsigned type
follows the same rules regardless of the representation used for the
signed type. A value 1 greater than the maximum value representable in
the unsigned type is either repeatedly added to, or repeatedly subtract
from, the value until the result is representable in the unsigned type
(6.3.1.3p2).
The machine instructions needed to obtain this result can be quite
different, depending upon which representation is used for the signed
type. However, the result of the conversion should be exactly the same
for all three representations, it depends only upon the initial value
represented and maximum representable value of the unsigned type.
[toc] | [prev] | [next] | [standalone]
| From | Johannes Bauer <dfnsonfsduifb@gmx.de> |
|---|---|
| Date | 2012-06-07 12:12 +0200 |
| Message-ID | <jqpuqh$aqu$1@news.albasani.net> |
| In reply to | #21911 |
On 06.06.2012 16:41, James Kuyper wrote: [...] > So the behavior you describe is not only allowed, but required, by the C > standard. James, thank you very much for the verbose and detailed explanation. In 15 years of C programming, I did not run into that caveat :-) Best regards, Johannes -- >> Wo hattest Du das Beben nochmal GENAU vorhergesagt? > Zumindest nicht öffentlich! Ah, der neueste und bis heute genialste Streich unsere großen Kosmologen: Die Geheim-Vorhersage. - Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$1@speranza.aioe.org>
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-06-07 06:44 -0400 |
| Message-ID | <jqq0m7$472$1@dont-email.me> |
| In reply to | #21924 |
On 06/07/2012 06:12 AM, Johannes Bauer wrote: > On 06.06.2012 16:41, James Kuyper wrote: > > [...] > >> So the behavior you describe is not only allowed, but required, by the C >> standard. > > James, thank you very much for the verbose and detailed explanation. In > 15 years of C programming, I did not run into that caveat :-) This issue comes up in almost every binary operation involving negative values and unsigned integers of a type with equal or greater integer conversion rank; if you've not noticed it before in 15 years of C programming, then you've probably been deliberately avoiding mixing negative values with unsigned types - which is generally a good idea. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Johannes Bauer <dfnsonfsduifb@gmx.de> |
|---|---|
| Date | 2012-06-07 13:31 +0200 |
| Message-ID | <jqq3er$k6u$1@news.albasani.net> |
| In reply to | #21926 |
On 07.06.2012 12:44, James Kuyper wrote: > if you've not noticed it before in 15 years of C > programming, then you've probably been deliberately avoiding mixing > negative values with unsigned types - which is generally a good idea. I try to do arithmetic, indexing and counting (i.e. loop variables) with signed types and use unsigned almost always only for bit operations (or where the well-defined overflow is needed). Has worked well so far :-) Best regards, Joe -- >> Wo hattest Du das Beben nochmal GENAU vorhergesagt? > Zumindest nicht öffentlich! Ah, der neueste und bis heute genialste Streich unsere großen Kosmologen: Die Geheim-Vorhersage. - Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$1@speranza.aioe.org>
[toc] | [prev] | [next] | [standalone]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2012-06-06 07:53 -0700 |
| Message-ID | <5d0dc068-e8a7-4548-9d9e-e1c1c9b33226@p27g2000vbl.googlegroups.com> |
| In reply to | #21907 |
On Jun 6, 2:55 pm, Johannes Bauer <dfnsonfsdu...@gmx.de> wrote: > > Is this really in accordance with the C standard or is gcc doing > something weird here? > James has given a complete technical answer, so I won't add to that. What I will say is that there's no universally accepted definition of what remainder/modulus means, so whatever intuition tells you[0], someone is going to consider it to be wrong. When it comes to remainders involving negatives, intuition is worthless. [0] My intuition, for example, tells me that -1 % 30 equals 29. My intuition is worthless too.
[toc] | [prev] | [next] | [standalone]
| From | Johannes Bauer <dfnsonfsduifb@gmx.de> |
|---|---|
| Date | 2012-06-07 12:15 +0200 |
| Message-ID | <jqpv0d$beq$1@news.albasani.net> |
| In reply to | #21912 |
On 06.06.2012 16:53, gwowen wrote: > When it comes to remainders involving negatives, intuition is > worthless. > > [0] My intuition, for example, tells me that -1 % 30 equals 29. My > intuition is worthless too. Well, it's always nice when intuition at least overlaps with the reality of compilers or interpreters :-) BTW, -1 % 30 == 29 in Python. I did know that C did not give up the sign, but I'd have expected for example -100 % 30 == -10 (it is 20 in Python). Anyways, it does so for signed/signed types, so I'm going to use these. Best regards, Joe -- >> Wo hattest Du das Beben nochmal GENAU vorhergesagt? > Zumindest nicht öffentlich! Ah, der neueste und bis heute genialste Streich unsere großen Kosmologen: Die Geheim-Vorhersage. - Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$1@speranza.aioe.org>
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-06-07 12:29 +0100 |
| Message-ID | <jqq3ap$iiu$1@dont-email.me> |
| In reply to | #21925 |
Johannes Bauer" <dfnsonfsduifb@gmx.de> wrote in message news:jqpv0d$beq$1@news.albasani.net... > On 06.06.2012 16:53, gwowen wrote: >> [0] My intuition, for example, tells me that -1 % 30 equals 29. My >> intuition is worthless too. > > Well, it's always nice when intuition at least overlaps with the reality > of compilers or interpreters :-) > > BTW, -1 % 30 == 29 in Python. I did know that C did not give up the > sign, but I'd have expected for example -100 % 30 == -10 (it is 20 in > Python). Anyways, it does so for signed/signed types, so I'm going to > use these. So -1%30 is -1 in C and 29 in Python. While -1%30u in C is 15. -1, 15 and 29; any other possible results for the same expression? -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Johannes Bauer <dfnsonfsduifb@gmx.de> |
|---|---|
| Date | 2012-06-07 13:43 +0200 |
| Message-ID | <jqq44l$m6s$1@news.albasani.net> |
| In reply to | #21927 |
On 07.06.2012 13:29, BartC wrote: >> BTW, -1 % 30 == 29 in Python. I did know that C did not give up the >> sign, but I'd have expected for example -100 % 30 == -10 (it is 20 in >> Python). Anyways, it does so for signed/signed types, so I'm going to >> use these. > > So -1%30 is -1 in C and 29 in Python. While -1%30u in C is 15. > > -1, 15 and 29; any other possible results for the same expression? If I understand James' post correct, in the expression -1 % 30u the "-1" is converted to UNSIGNED_MAX (which happens to be (2^32)-1 on my system). Since int IIRC is only required to have >= 16 bits, one could image a n-bit system in which the expression would evaluate to something different. In particular, if bits % 4 == 0, it evaluates to 15. For bits % 4 result 0 15 1 1 2 3 3 7 So I think the expression can be either -1, 15, 29, 1, 3 or 7 depending on the language and platform :-) Best regards, Johannes -- >> Wo hattest Du das Beben nochmal GENAU vorhergesagt? > Zumindest nicht öffentlich! Ah, der neueste und bis heute genialste Streich unsere großen Kosmologen: Die Geheim-Vorhersage. - Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$1@speranza.aioe.org>
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-06-07 07:46 -0400 |
| Message-ID | <jqq4a7$nse$1@dont-email.me> |
| In reply to | #21927 |
On 6/7/2012 7:29 AM, BartC wrote:
> Johannes Bauer" <dfnsonfsduifb@gmx.de> wrote in message
> news:jqpv0d$beq$1@news.albasani.net...
>> On 06.06.2012 16:53, gwowen wrote:
>
>>> [0] My intuition, for example, tells me that -1 % 30 equals 29. My
>>> intuition is worthless too.
>>
>> Well, it's always nice when intuition at least overlaps with the reality
>> of compilers or interpreters :-)
>>
>> BTW, -1 % 30 == 29 in Python. I did know that C did not give up the
>> sign, but I'd have expected for example -100 % 30 == -10 (it is 20 in
>> Python). Anyways, it does so for signed/signed types, so I'm going to
>> use these.
>
> So -1%30 is -1 in C and 29 in Python. While -1%30u in C is 15.
-1%30u in C *can be* 15.
> -1, 15 and 29; any other possible results for the same expression?
In C, the possible results are 1, 3, 7, 15.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-06-07 20:58 +0100 |
| Message-ID | <0.38e73e0042857288d2b5.20120607205812BST.87d35aao8b.fsf@bsb.me.uk> |
| In reply to | #21930 |
Eric Sosman <esosman@ieee-dot-org.invalid> writes: > On 6/7/2012 7:29 AM, BartC wrote: >> Johannes Bauer" <dfnsonfsduifb@gmx.de> wrote in message >> news:jqpv0d$beq$1@news.albasani.net... >>> On 06.06.2012 16:53, gwowen wrote: >> >>>> [0] My intuition, for example, tells me that -1 % 30 equals 29. My >>>> intuition is worthless too. >>> >>> Well, it's always nice when intuition at least overlaps with the reality >>> of compilers or interpreters :-) >>> >>> BTW, -1 % 30 == 29 in Python. I did know that C did not give up the >>> sign, but I'd have expected for example -100 % 30 == -10 (it is 20 in >>> Python). Anyways, it does so for signed/signed types, so I'm going to >>> use these. >> >> So -1%30 is -1 in C and 29 in Python. While -1%30u in C is 15. > > -1%30u in C *can be* 15. > >> -1, 15 and 29; any other possible results for the same expression? > > In C, the possible results are 1, 3, 7, 15. I think -1 is also possible on those awkward systems where UINT_MAX == INT_MAX. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-06-07 19:58 -0400 |
| Message-ID | <jqrf7c$hdo$1@dont-email.me> |
| In reply to | #21934 |
On 6/7/2012 3:58 PM, Ben Bacarisse wrote:
> Eric Sosman<esosman@ieee-dot-org.invalid> writes:
>
>> On 6/7/2012 7:29 AM, BartC wrote:
>>> Johannes Bauer"<dfnsonfsduifb@gmx.de> wrote in message
>>> news:jqpv0d$beq$1@news.albasani.net...
>>>> On 06.06.2012 16:53, gwowen wrote:
>>>
>>>>> [0] My intuition, for example, tells me that -1 % 30 equals 29. My
>>>>> intuition is worthless too.
>>>>
>>>> Well, it's always nice when intuition at least overlaps with the reality
>>>> of compilers or interpreters :-)
>>>>
>>>> BTW, -1 % 30 == 29 in Python. I did know that C did not give up the
>>>> sign, but I'd have expected for example -100 % 30 == -10 (it is 20 in
>>>> Python). Anyways, it does so for signed/signed types, so I'm going to
>>>> use these.
>>>
>>> So -1%30 is -1 in C and 29 in Python. While -1%30u in C is 15.
>>
>> -1%30u in C *can be* 15.
>>
>>> -1, 15 and 29; any other possible results for the same expression?
>>
>> In C, the possible results are 1, 3, 7, 15.
>
> I think -1 is also possible on those awkward systems where UINT_MAX ==
> INT_MAX.
Quite right; thanks for correcting my oversight.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-06-08 02:20 -0700 |
| Message-ID | <kfnr4tqgnwz.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #21934 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > Eric Sosman <esosman@ieee-dot-org.invalid> writes: > >> On 6/7/2012 7:29 AM, BartC wrote: >>> Johannes Bauer" <dfnsonfsduifb@gmx.de> wrote in message >>> news:jqpv0d$beq$1@news.albasani.net... >>>> On 06.06.2012 16:53, gwowen wrote: >>> >>>>> [0] My intuition, for example, tells me that -1 % 30 equals 29. My >>>>> intuition is worthless too. >>>> >>>> Well, it's always nice when intuition at least overlaps with the reality >>>> of compilers or interpreters :-) >>>> >>>> BTW, -1 % 30 == 29 in Python. I did know that C did not give up the >>>> sign, but I'd have expected for example -100 % 30 == -10 (it is 20 in >>>> Python). Anyways, it does so for signed/signed types, so I'm going to >>>> use these. >>> >>> So -1%30 is -1 in C and 29 in Python. While -1%30u in C is 15. >> >> -1%30u in C *can be* 15. >> >>> -1, 15 and 29; any other possible results for the same expression? >> >> In C, the possible results are 1, 3, 7, 15. > > I think -1 is also possible on those awkward systems where UINT_MAX == > INT_MAX. Sort of. This curious behavior was not present in C90 or in the original C99. It was added via a TC (it appears in N1124) as a result of Defect Report 230. However, subsequently it was acknowledged that the strange effect on the promotion rules was an unintended consequence of a poor wording choice to address the DR. This has since been corrected in C11 -- under C11 unsigned int is never 'promoted' to int even if UINT_MAX == INT_MAX. Hence the expression -1%30u can never be -1 (or any negative number) under the current standard.
[toc] | [prev] | [next] | [standalone]
| From | Johannes Bauer <dfnsonfsduifb@gmx.de> |
|---|---|
| Date | 2012-06-08 11:33 +0200 |
| Message-ID | <jqsgu1$4so$1@news.albasani.net> |
| In reply to | #21947 |
On 08.06.2012 11:20, Tim Rentsch wrote: >> I think -1 is also possible on those awkward systems where UINT_MAX == >> INT_MAX. > > Sort of. This curious behavior was not present in C90 or > in the original C99. It was added via a TC (it appears > in N1124) as a result of Defect Report 230. However, > subsequently it was acknowledged that the strange effect > on the promotion rules was an unintended consequence of a > poor wording choice to address the DR. This has since > been corrected in C11 -- under C11 unsigned int is never > 'promoted' to int even if UINT_MAX == INT_MAX. Hence the > expression -1%30u can never be -1 (or any negative number) > under the current standard. Wow -- I really don't feel bad about tripping over this now. It *is* indeed confusion and without a *lot* of insight into the standard it is quite hard to tell what the expression will evaluate to on different platforms. Best regards, Joe -- >> Wo hattest Du das Beben nochmal GENAU vorhergesagt? > Zumindest nicht öffentlich! Ah, der neueste und bis heute genialste Streich unsere großen Kosmologen: Die Geheim-Vorhersage. - Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$1@speranza.aioe.org>
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-06-08 12:30 +0100 |
| Message-ID | <0.98a376f61e7465ca9f4c.20120608123059BST.877gvi9h1o.fsf@bsb.me.uk> |
| In reply to | #21948 |
Johannes Bauer <dfnsonfsduifb@gmx.de> writes: > On 08.06.2012 11:20, Tim Rentsch wrote: > >>> I think -1 is also possible on those awkward systems where UINT_MAX == >>> INT_MAX. >> >> Sort of. This curious behavior was not present in C90 or >> in the original C99. It was added via a TC (it appears >> in N1124) as a result of Defect Report 230. However, >> subsequently it was acknowledged that the strange effect >> on the promotion rules was an unintended consequence of a >> poor wording choice to address the DR. This has since >> been corrected in C11 -- under C11 unsigned int is never >> 'promoted' to int even if UINT_MAX == INT_MAX. Hence the >> expression -1%30u can never be -1 (or any negative number) >> under the current standard. > > Wow -- I really don't feel bad about tripping over this now. It *is* > indeed confusion and without a *lot* of insight into the standard it is > quite hard to tell what the expression will evaluate to on different > platforms. I don't want to make you feel bad again, but this last case is one of the oddest corners of C and can be quite safely ignored by almost everyone (indeed by everyone, soon, if C11 gets a hold). The main fact, that mixed int and unsigned int arithmetic is done by converting the int operand to unsigned int, is commonplace and needs to be kept in mind for those times when it will matter. The fact that it's happening is often masked by implementations that use 2's complement and define the unsigned to int conversion as simply "stuffing the bits back in there". However int x; /* ... */ x = x + 1u; can raise a signal when x is, say, -1 on systems that define the conversion of out-of-range values to int as doing so. On most systems it "just works" as if 1 had been used in place of 1u. Real examples are often more disguised since you might be adding a size_t value to x. The fact that -1 % 30u can have different values on different systems is just a reflection of the fact that UINT_MAX can have different values depending on the number of bits used by unsigned int. So, once again, my intent is not to make you feel you should have known all this, but simply to say that it is *worth* knowing, and that it's not actually as complicated as this thread seems to suggest. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-06-08 11:12 -0700 |
| Message-ID | <kfnehpphdvd.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #21950 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > Johannes Bauer <dfnsonfsduifb@gmx.de> writes: > >> On 08.06.2012 11:20, Tim Rentsch wrote: >> >>>> I think -1 is also possible on those awkward systems where UINT_MAX == >>>> INT_MAX. >>> >>> Sort of. This curious behavior was not present in C90 or >>> in the original C99. It was added via a TC (it appears >>> in N1124) as a result of Defect Report 230. However, >>> subsequently it was acknowledged that the strange effect >>> on the promotion rules was an unintended consequence of a >>> poor wording choice to address the DR. This has since >>> been corrected in C11 -- under C11 unsigned int is never >>> 'promoted' to int even if UINT_MAX == INT_MAX. Hence the >>> expression -1%30u can never be -1 (or any negative number) >>> under the current standard. >> >> Wow -- I really don't feel bad about tripping over this now. It *is* >> indeed confusion and without a *lot* of insight into the standard it is >> quite hard to tell what the expression will evaluate to on different >> platforms. > > I don't want to make you feel bad again, but this last case is one of > the oddest corners of C and can be quite safely ignored by almost > everyone (indeed by everyone, soon, if C11 gets a hold). > > The main fact, that mixed int and unsigned int arithmetic is done by > converting the int operand to unsigned int, is commonplace and needs to > be kept in mind for those times when it will matter. The fact that it's > happening is often masked by implementations that use 2's complement and > define the unsigned to int conversion as simply "stuffing the bits back > in there". However > > int x; > /* ... */ > x = x + 1u; > > can raise a signal when x is, say, -1 on systems that define the > conversion of out-of-range values to int as doing so. [snip] Forgive me if this is a stupid question -- can you explain how starting with x == -1 can give rise to anything other than x == 0 after the assignment? To me the behavior here looks well-defined.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-06-08 20:37 +0100 |
| Message-ID | <0.ab071a5a81020335715d.20120608203736BST.87obot8uin.fsf@bsb.me.uk> |
| In reply to | #21980 |
Tim Rentsch <txr@alumni.caltech.edu> writes: > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: <snip> >> The main fact, that mixed int and unsigned int arithmetic is done by >> converting the int operand to unsigned int, is commonplace and needs to >> be kept in mind for those times when it will matter. The fact that it's >> happening is often masked by implementations that use 2's complement and >> define the unsigned to int conversion as simply "stuffing the bits back >> in there". However >> >> int x; >> /* ... */ >> x = x + 1u; >> >> can raise a signal when x is, say, -1 on systems that define the >> conversion of out-of-range values to int as doing so. [snip] > > Forgive me if this is a stupid question -- can you explain how > starting with x == -1 can give rise to anything other than x == 0 > after the assignment? To me the behavior here looks well-defined. Yes, I should have said "x = -2" or, indeed, any int value < 0 other than the one I picked. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-06-08 13:44 -0700 |
| Message-ID | <ln1ulpcz46.fsf@nuthaus.mib.org> |
| In reply to | #21980 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
[...]
>> However
>>
>> int x;
>> /* ... */
>> x = x + 1u;
>>
>> can raise a signal when x is, say, -1 on systems that define the
>> conversion of out-of-range values to int as doing so. [snip]
>
> Forgive me if this is a stupid question -- can you explain how
> starting with x == -1 can give rise to anything other than x == 0
> after the assignment? To me the behavior here looks well-defined.
I was in the middle of explaining why it's not well-defined when
I realized that it actually is.
The operands of "+" are of types int and unsigned int. The "usual
arithmetic conversions" cause the left operand to be converted
from int to unsigned int. The int value -1 is outside the range of
the target type -- but int-to-unsigned conversion is well defined,
and yields UINT_MAX. UINT_MAX + 1u yields 0u, and the assignment
converts 0u (type unsigned int) to 0 (type int).
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-06-08 22:22 +0100 |
| Message-ID | <0.03126f64f4c864d84bf5.20120608222200BST.87d3598pon.fsf@bsb.me.uk> |
| In reply to | #22011 |
Keith Thompson <kst-u@mib.org> writes: > Tim Rentsch <txr@alumni.caltech.edu> writes: > [...] >>> However >>> >>> int x; >>> /* ... */ >>> x = x + 1u; >>> >>> can raise a signal when x is, say, -1 on systems that define the >>> conversion of out-of-range values to int as doing so. [snip] >> >> Forgive me if this is a stupid question -- can you explain how >> starting with x == -1 can give rise to anything other than x == 0 >> after the assignment? To me the behavior here looks well-defined. > > I was in the middle of explaining why it's not well-defined when > I realized that it actually is. > > The operands of "+" are of types int and unsigned int. The "usual > arithmetic conversions" cause the left operand to be converted > from int to unsigned int. The int value -1 is outside the range of > the target type -- but int-to-unsigned conversion is well defined, > and yields UINT_MAX. UINT_MAX + 1u yields 0u, and the assignment > converts 0u (type unsigned int) to 0 (type int). Yes. Originally I wrote it without an example value for x, but then I thought "I'll give an example value to make it concrete" and I went and chose the only negative value that invalidate the example! -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Johannes Bauer <dfnsonfsduifb@gmx.de> |
|---|---|
| Date | 2012-06-10 10:56 +0200 |
| Message-ID | <jr1nf9$t7f$1@news.albasani.net> |
| In reply to | #21950 |
On 08.06.2012 13:30, Ben Bacarisse wrote: > I don't want to make you feel bad again, but this last case is one of > the oddest corners of C and can be quite safely ignored by almost > everyone (indeed by everyone, soon, if C11 gets a hold). No worries, you haven't made me feel bad again :-) Much rather curious: In what ways does C11 change this behavior? I haven't looked into C11 at all yet and am really interested what that change could be (while still remaining backwards compatible). Best regards, Joe -- >> Wo hattest Du das Beben nochmal GENAU vorhergesagt? > Zumindest nicht öffentlich! Ah, der neueste und bis heute genialste Streich unsere großen Kosmologen: Die Geheim-Vorhersage. - Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$1@speranza.aioe.org>
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web