Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #21907 > unrolled thread

Signed mod unsigned

Started byJohannes Bauer <dfnsonfsduifb@gmx.de>
First post2012-06-06 15:55 +0200
Last post2012-06-07 17:08 -0400
Articles 20 on this page of 30 — 9 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#21907 — Signed mod unsigned

FromJohannes Bauer <dfnsonfsduifb@gmx.de>
Date2012-06-06 15:55 +0200
SubjectSigned 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]


#21911

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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]


#21924

FromJohannes Bauer <dfnsonfsduifb@gmx.de>
Date2012-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]


#21926

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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]


#21928

FromJohannes Bauer <dfnsonfsduifb@gmx.de>
Date2012-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]


#21912

Fromgwowen <gwowen@gmail.com>
Date2012-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]


#21925

FromJohannes Bauer <dfnsonfsduifb@gmx.de>
Date2012-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]


#21927

From"BartC" <bc@freeuk.com>
Date2012-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]


#21929

FromJohannes Bauer <dfnsonfsduifb@gmx.de>
Date2012-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]


#21930

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-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]


#21934

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#21939

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-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]


#21947

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-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]


#21948

FromJohannes Bauer <dfnsonfsduifb@gmx.de>
Date2012-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]


#21950

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#21980

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-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]


#22002

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#22011

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#22017

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#22088

FromJohannes Bauer <dfnsonfsduifb@gmx.de>
Date2012-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