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 | 10 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 2 of 2 — ← Prev page 1 [2]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-06-10 14:40 +0100 |
| Message-ID | <0.d1bca05c7631f9b50582.20120610144036BST.87fwa3xp2j.fsf@bsb.me.uk> |
| In reply to | #22088 |
Johannes Bauer <dfnsonfsduifb@gmx.de> writes:
> 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).
What's happened (thanks, Tim, for making me go look) is that the phrase
"other than int or unsigned int" has been added to exclude them from the
integer promotions. This means that unsigned int is never promoted to
int, even on those odd systems where the rule would otherwise apply ("if
an int can represent all of the values of the original type [...] the
value is converted to an int").
This is not backwards compatible on those odd implementations, but since
it seems the effect of the old rule on unsigned int was introduced
inadvertently, the committee must have felt it worth breaking
compatibility to tidy this up.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-06-11 15:49 -0700 |
| Message-ID | <lnfwa1a2h7.fsf@nuthaus.mib.org> |
| In reply to | #22092 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Johannes Bauer <dfnsonfsduifb@gmx.de> writes:
>> 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).
>
> What's happened (thanks, Tim, for making me go look) is that the phrase
> "other than int or unsigned int" has been added to exclude them from the
> integer promotions. This means that unsigned int is never promoted to
> int, even on those odd systems where the rule would otherwise apply ("if
> an int can represent all of the values of the original type [...] the
> value is converted to an int").
>
> This is not backwards compatible on those odd implementations, but since
> it seems the effect of the old rule on unsigned int was introduced
> inadvertently, the committee must have felt it worth breaking
> compatibility to tidy this up.
It's not backwards compatible with implementations where an int can old
all the values of unsigned int that followed the letter of the standard.
I rather doubt that there are any such implementations in the real
world. My guess (and it's only a guess) is that there are very few
implementations with UINT_MAX == INT_MAX, and of those implementations
few if any fully conformed to C99.
--
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 | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-06-24 09:32 -0700 |
| Message-ID | <kfnd34ou0v4.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #22092 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Johannes Bauer <dfnsonfsduifb@gmx.de> writes:
>
>> 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).
>
> What's happened (thanks, Tim, for making me go look) is that the phrase
> "other than int or unsigned int" has been added to exclude them from the
> integer promotions. This means that unsigned int is never promoted to
> int, even on those odd systems where the rule would otherwise apply ("if
> an int can represent all of the values of the original type [...] the
> value is converted to an int").
>
> This is not backwards compatible on those odd implementations, but since
> it seems the effect of the old rule on unsigned int was introduced
> inadvertently, the committee must have felt it worth breaking
> compatibility to tidy this up.
I think of this not as an incompatibility but just as correcting a
mistake that they (may have) thought no one implemented anyway.
Remember, this behavior was not in C99 originally; it was added
in a TC. For an implementation to be affected by it, it would
require: one, that the change in the TC be noticed; two, that
the implementor realize the consequences of the bad wording on
such promotions; and three, that the implementation be one of
those for which the bad wording was relevant. The likelihood of
all three of those occurring, especially given the relative lack
of attention given to C99 and the dearth of fulling conforming C99
compilers, seems low enough to make concerns about compatibility
be pretty much a non-issue.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-06-08 11:05 -0700 |
| Message-ID | <kfnipf1he6y.fsf@x-alumni2.alumni.caltech.edu> |
| 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.
In practice it isn't hard to say what the result will be, because
the "pathological" implementations with such bizarre behavior are
very rare (indeed, I conjecture that none exist), and very likely
a developer would know if his platform had such issues. Granted,
the rule for converting the signed type to the unsigned type does
need to be known, but people who use mixed-mode arithmetic should
be familiar with that for other reasons (eg, comparisons).
When C was originally standardized, there was a big debate about
how to do integer promotions (in particular, should types like
'unsigned short' promote to signed int or unsigned int?). So
here's another case for you:
unsigned short us_30 = 30;
unsigned int ui_30 = 30;
int minus_one = -1;
// now, what is the result of
if( minus_one % us_30 == minus_one % ui_30 ) ... etc ...
Does the "etc" get executed or not? You might enjoy looking
into the Standard and see what you can make of this question.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-06-08 12:06 +0100 |
| Message-ID | <0.a8daec7df0ed7476f02f.20120608120659BST.87d35a9i5o.fsf@bsb.me.uk> |
| In reply to | #21947 |
Tim Rentsch <txr@alumni.caltech.edu> writes: > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > >> Eric Sosman <esosman@ieee-dot-org.invalid> writes: <snip> >>> -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. Well that's pleasing to know, although I've never had to wrestle with such an implementation. As far as I can tell, if it followed C99 to the letter, the only way to do unsigned arithmetic would be to force one or more of the operands to be "wider" than unsigned int. I put wider in quotes because I think you can do it even if there no type that is actually wider because of the way conversion rank is defined. Thus -1%30ul can't be -1 even on the most literal C99 implementation. Still, it's good that this has been tidied up. It will save much nit-picking time here. I wonder if it will have any other effect on the world. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-06-08 11:32 -0700 |
| Message-ID | <kfnaa0dhcye.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #21949 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>
>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>
>>> Eric Sosman <esosman@ieee-dot-org.invalid> writes:
> <snip>
>>>> -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.
>
> Well that's pleasing to know, although I've never had to
> wrestle with such an implementation. As far as I can tell, if
> it followed C99 to the letter, the only way to do unsigned
> arithmetic would be to force one or more of the operands to be
> "wider" than unsigned int. [snip]
Most likely there are no such implementations. Assuming
however that such hardware platforms still exist, implementors
determined to do a C99 implementation on them would be well
advised to have INT_MAX == UINT_MAX/2 + 1, by making the
high-order bit of a hardware integer value be a 'padding bit'
as far as the C implementation is concerned. Taking this
approach we could still get a full range of values for
int-only operations (taking advantage of "undefined behavior"
for values that have that bit set), but signed/unsigned
mixtures would not behave pathologically.
(Under the heading of 'note to self': I really should get in
the habit of putting
#include <limits.h>
#if UINT_MAX == INT_MAX
#error UINT_MAX == INT_MAX -- need I say more
#endif
in my common header files.)
[toc] | [prev] | [next] | [standalone]
| From | Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> |
|---|---|
| Date | 2012-06-06 22:15 +0000 |
| Message-ID | <jqokpp$oui$1@speranza.aioe.org> |
| In reply to | #21907 |
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?
This looks like a compiler bug. I would report it to a Gcc mailing list.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-06-06 18:29 -0400 |
| Message-ID | <4FCFD9B2.9090507@verizon.net> |
| In reply to | #21919 |
On 06/06/2012 06:15 PM, Edward Rutherford wrote:
> 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?
>
> This looks like a compiler bug. I would report it to a Gcc mailing list.
I explained in my response why I believe that this behavior is not
merely allowed, but mandated, by the C standard. Do you disagree? If so,
on what grounds?
[toc] | [prev] | [next] | [standalone]
| From | Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> |
|---|---|
| Date | 2012-06-07 20:44 +0000 |
| Message-ID | <jqr3rr$vr$1@speranza.aioe.org> |
| In reply to | #21920 |
James Kuyper wrote:
> On 06/06/2012 06:15 PM, Edward Rutherford wrote:
>> 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?
>>
>> This looks like a compiler bug. I would report it to a Gcc mailing
>> list.
>
> I explained in my response why I believe that this behavior is not
> merely allowed, but mandated, by the C standard. Do you disagree? If so,
> on what grounds?
This outcome just seems counterintuitive to me. Even if it is permitted
by the C standard, this option is kinda retarded and I'd say the compiler
has poor quality of implementation.
Best regards,
E.P.R.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-06-07 17:08 -0400 |
| Message-ID | <4FD11858.3040507@verizon.net> |
| In reply to | #21935 |
On 06/07/2012 04:44 PM, Edward Rutherford wrote:
> James Kuyper wrote:
>
>> On 06/06/2012 06:15 PM, Edward Rutherford wrote:
>>> 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?
>>>
>>> This looks like a compiler bug. I would report it to a Gcc mailing
>>> list.
>>
>> I explained in my response why I believe that this behavior is not
>> merely allowed, but mandated, by the C standard. Do you disagree? If so,
>> on what grounds?
>
> This outcome just seems counterintuitive to me. Even if it is permitted
> by the C standard, this option is kinda retarded and I'd say the compiler
> has poor quality of implementation.
It's not merely permitted; it's not an option; it's required. The phrase
"Quality of implementation" is normally considered to apply only to
issues where the standard gives a conforming implementation freedom to
choose how something is done. The only freedom that the implementation
has that's relevant to this program is in number of value bits in an
unsigned int. You're not suggesting, I hope, that choosing 32 for that
number gives the implementation a low QoI? It's a pretty popular choice.
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c
csiph-web