Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #19072 > unrolled thread
| Started by | Francois Grieu <fgrieu@gmail.com> |
|---|---|
| First post | 2012-03-27 16:32 +0200 |
| Last post | 2012-03-27 23:22 -0700 |
| Articles | 15 — 8 participants |
Back to article view | Back to comp.lang.c
does 0<(unsigned short)0x8000 hold? Francois Grieu <fgrieu@gmail.com> - 2012-03-27 16:32 +0200
Re: does 0<(unsigned short)0x8000 hold? Harald van Dijk <haraldvdijk@gmail.com> - 2012-03-27 09:09 -0700
Re: does 0<(unsigned short)0x8000 hold? James Kuyper <jameskuyper@verizon.net> - 2012-03-27 12:15 -0400
Re: does 0<(unsigned short)0x8000 hold? Francois Grieu <fgrieu@gmail.com> - 2012-03-27 18:54 +0200
Re: does 0<(unsigned short)0x8000 hold? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-27 17:23 +0100
Re: does 0<(unsigned short)0x8000 hold? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-27 20:12 +0100
Re: does 0<(unsigned short)0x8000 hold? James Kuyper <jameskuyper@verizon.net> - 2012-03-27 15:32 -0400
Re: does 0<(unsigned short)0x8000 hold? Harald van Dijk <haraldvdijk@gmail.com> - 2012-03-27 12:47 -0700
Re: does 0<(unsigned short)0x8000 hold? James Kuyper <jameskuyper@verizon.net> - 2012-03-27 16:11 -0400
Re: does 0<(unsigned short)0x8000 hold? Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-27 10:32 -0700
Re: does 0<(unsigned short)0x8000 hold? Francois Grieu <fgrieu@gmail.com> - 2012-03-28 15:08 +0200
Re: does 0<(unsigned short)0x8000 hold? Philipp Klaus Krause <pkk@spth.de> - 2012-03-28 09:07 +0200
Re: does 0<(unsigned short)0x8000 hold? Francois Grieu <fgrieu@gmail.com> - 2012-03-28 16:15 +0200
Re: does 0<(unsigned short)0x8000 hold? Kaz Kylheku <kaz@kylheku.com> - 2012-03-28 14:26 +0000
Re: does 0<(unsigned short)0x8000 hold? Peter Nilsson <airia@acay.com.au> - 2012-03-27 23:22 -0700
| From | Francois Grieu <fgrieu@gmail.com> |
|---|---|
| Date | 2012-03-27 16:32 +0200 |
| Subject | does 0<(unsigned short)0x8000 hold? |
| Message-ID | <4f71cf85$0$21948$426a74cc@news.free.fr> |
I just tested my code for portability problems on systems
where int is 16-bit, and found one such system where
#include <stdio.h>
int main(void)
{
printf("%d\n", 0<(unsigned short)0x8000 );
return 0;
}
outputs 0. If I change 0< to 0u<, the output is 1.
Is that a bug in this compiler, w.r.t. C99?
As an aside, 6.5.8p2 puzzles me; it reads:
"One of the following shall hold:
— both operands have real type;
— both operands are pointers to qualified or unqualified versions
of compatible object types; or
— both operands are pointers to qualified or unqualified versions
of compatible incomplete types.
(..)"
Would my example imply conversion to *real*, at least conceptually ?!
As an aside of the aside, I do not understand the third option in
the constraint, and it has been removed in N1570.
TIA,
Francois Grieu
[toc] | [next] | [standalone]
| From | Harald van Dijk <haraldvdijk@gmail.com> |
|---|---|
| Date | 2012-03-27 09:09 -0700 |
| Message-ID | <ffd57622-c7cf-472b-b353-dff5f66751ec@gw9g2000vbb.googlegroups.com> |
| In reply to | #19072 |
On Mar 27, 4:32 pm, Francois Grieu <fgr...@gmail.com> wrote:
> I just tested my code for portability problems on systems
> where int is 16-bit, and found one such system where
>
> #include <stdio.h>
> int main(void)
> {
> printf("%d\n", 0<(unsigned short)0x8000 );
> return 0;
> }
>
> outputs 0. If I change 0< to 0u<, the output is 1.
>
> Is that a bug in this compiler, w.r.t. C99?
unsigned short promotes to int if all values can be represented in
int, otherwise it promotes to unsigned int (6.3.1.1p2), so yes, that
looks like a bug.
> As an aside, 6.5.8p2 puzzles me; it reads:
> "One of the following shall hold:
> — both operands have real type;
> — both operands are pointers to qualified or unqualified versions
> of compatible object types; or
> — both operands are pointers to qualified or unqualified versions
> of compatible incomplete types.
> (..)"
>
> Would my example imply conversion to *real*, at least conceptually ?!
Integer types and floating point types are together called real types
(6.2.5p17); yes, there is an implicit conversion to a real type, and
that type is unsigned int.
> As an aside of the aside, I do not understand the third option in
> the constraint, and it has been removed in N1570.
It seems to allow comparisons between two void * values, or between
two int(*)[] values. It seems silly to allow that but not also allow a
comparison between f.e. a void * and a char *, but I'm not sure why it
was removed entirely.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-03-27 12:15 -0400 |
| Message-ID | <4F71E7AF.7000500@verizon.net> |
| In reply to | #19072 |
On 03/27/2012 10:32 AM, Francois Grieu wrote:
> I just tested my code for portability problems on systems
> where int is 16-bit, and found one such system where
>
> #include <stdio.h>
> int main(void)
> {
> printf("%d\n", 0<(unsigned short)0x8000 );
> return 0;
> }
>
> outputs 0. If I change 0< to 0u<, the output is 1.
>
> Is that a bug in this compiler, w.r.t. C99?
INT_MAX is allowed to be as low as 0x7FFF, and that's presumably true on
a 16-bit system (though there's always been a lot of debate about what
"N-bit system" really means). If so, conversion of (unsigned
short)0x8000 to int would produce a negative value unless int has a
sign-and-magnitude type. But if INT_MAX is 0x7FFF, then (unsigned
char)0x8000 must be promoted to "unsigned int", rather than "int"
(6.3.1.1p2), and therefore 0 must also be converted to unsigned int,
before evaluating the expression. As a result that expression would be
equivalent to 0U < 0x8000U, which is still guaranteed to have a value of
1. I'd say this is a bug in the compiler.
> As an aside, 6.5.8p2 puzzles me; it reads:
> "One of the following shall hold:
> — both operands have real type;
> — both operands are pointers to qualified or unqualified versions
> of compatible object types; or
> — both operands are pointers to qualified or unqualified versions
> of compatible incomplete types.
> (..)"
>
> Would my example imply conversion to *real*, at least conceptually ?!
"The integer and real floating types are collectively called
real types." (6.2.5p17), therefore no conversion to a real type is
required. As a result, the usual arithmetic conversions require that the
integer promotions be applied to both operands (6.3.1.8p1).
> As an aside of the aside, I do not understand the third option in
> the constraint, ...
You're referring to "both operands [of a relational operator] are
pointers to qualified or unqualified versions of compatible incomplete
types."? I think the trickiest concept used in that sentence is
"pointers to ... compatible incomplete types". Is that what you're
having trouble with? Each of the following declarations defines a
pointer to an incomplete type:
int (*p_incomplete_array)[];
struct flexible_array
{
size_t count;
int member[];
} *pfa;
// No definition provided for struct my_struct
struct my_struct *pms;
void *pv;
> ... and it has been removed in N1570.
I can confirm that it has been removed. The implication would seem to be
that it's no longer possible to compare pointers to incomplete types for
relative order. I find this surprising. Am I misunderstanding it? If not
was it deliberately removed, or an accident? If deliberate, what was the
rationale for doing so?
[toc] | [prev] | [next] | [standalone]
| From | Francois Grieu <fgrieu@gmail.com> |
|---|---|
| Date | 2012-03-27 18:54 +0200 |
| Message-ID | <4f71f0d5$0$13215$426a74cc@news.free.fr> |
| In reply to | #19074 |
On 27/03/2012 18:15, James Kuyper wrote:
> On 03/27/2012 10:32 AM, Francois Grieu wrote:
>> I just tested my code for portability problems on systems
>> where int is 16-bit, and found one such system where
>>
>> #include <stdio.h>
>> int main(void)
>> {
>> printf("%d\n", 0<(unsigned short)0x8000 );
>> return 0;
>> }
>>
>> outputs 0. If I change 0< to 0u<, the output is 1.
>>
>> Is that a bug in this compiler, w.r.t. C99?
>
> (..) that expression would be equivalent to 0U < 0x8000U (..)
I get to that also. It is a bug in the compiler. Main question solved.
>> As an aside, 6.5.8p2 puzzles me; it reads:
>> "One of the following shall hold:
>> — both operands have real type;
>> — both operands are pointers to qualified or unqualified versions
>> of compatible object types; or
>> — both operands are pointers to qualified or unqualified versions
>> of compatible incomplete types.
>> (..)"
>>
>> Would my example imply conversion to *real*, at least conceptually ?!
>
> "The integer and real floating types are collectively called
> real types." (6.2.5p17),
Ah! First aside solved. I read "real" and understood "floating".
>> As an aside of the aside, I do not understand the third option in
>> the constraint, ...
> (..) I think the trickiest concept used in that sentence is
> "pointers to ... compatible incomplete types". Is that what you're
> having trouble with?
Yes.
> Each of the following declarations defines a
> pointer to an incomplete type:
>
> int (*p_incomplete_array)[];
> struct flexible_array
> {
> size_t count;
> int member[];
> } *pfa;
> // No definition provided for struct my_struct
> struct my_struct *pms;
> void *pv;
Ah, thanks for the illustration! Now I see 6.2.5p1, defining
"incomplete type" as one of "types that describe objects but lack
information needed to determine their sizes".
So when I'm using a pointer to void, I'm using an "incomplete type",
like Mr. Jourdain is using prose [I choose to never use the other
forms, for portability].
>> ... and it has been removed in N1570.
>
> I can confirm that it has been removed. The implication would seem to be
> that it's no longer possible to compare pointers to incomplete types for
> relative order. I find this surprising. Am I misunderstanding it? If not
> was it deliberately removed, or an accident? If deliberate, what was the
> rationale for doing so?
Indeed, comparing pointers to void referring to elements in the same
struct or array seems like a feature that could help on occasions, was
OK in C99, and seems gone from C2011 for no apparent reason. I second
the question.
Francois Grieu
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-03-27 17:23 +0100 |
| Message-ID | <0.64ccc68ce1fe7a16cc7d.20120327172357BST.878vimnhb6.fsf@bsb.me.uk> |
| In reply to | #19072 |
Francois Grieu <fgrieu@gmail.com> writes:
> I just tested my code for portability problems on systems
> where int is 16-bit, and found one such system where
>
> #include <stdio.h>
> int main(void)
> {
> printf("%d\n", 0<(unsigned short)0x8000 );
> return 0;
> }
>
> outputs 0. If I change 0< to 0u<, the output is 1.
>
> Is that a bug in this compiler, w.r.t. C99?
It looks wrong to me. GCC says 1 on my machine and that's what I'd
expect.
> As an aside, 6.5.8p2 puzzles me; it reads:
> "One of the following shall hold:
> — both operands have real type;
> — both operands are pointers to qualified or unqualified versions
> of compatible object types; or
> — both operands are pointers to qualified or unqualified versions
> of compatible incomplete types.
> (..)"
>
> Would my example imply conversion to *real*, at least conceptually ?!
Depends on what "conceptually" means here! 6.2.5 p 17 says:
The type char, the signed and unsigned integer types, and the
enumerated types are collectively called integer types. The integer
and real floating types are collectively called real types.
so it's really just a catch-all term like arithmetic type.
> As an aside of the aside, I do not understand the third option in
> the constraint, and it has been removed in N1570.
It makes sense to remove it. You can compare two pointers to incomplete
types for equality, but <, >, etc are defined in terms of sub-objects in
a array, so only pointers to object type make good sense.
Some previously well-defined code (albeit not very useful code) will now
require a diagnostic.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-03-27 20:12 +0100 |
| Message-ID | <0.5a4e1aeae0758d15ba6c.20120327201205BST.87398too3e.fsf@bsb.me.uk> |
| In reply to | #19075 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > Francois Grieu <fgrieu@gmail.com> writes: <snip> >> As an aside of the aside, I do not understand the third option in >> the constraint, and it has been removed in N1570. > > It makes sense to remove it. No it didn't! This part of my reply was nonsense. It's perfectly possible to well-define relative comparisons between pointers to incomplete types. It's good to see that the change is just due to a change in terminology. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-03-27 15:32 -0400 |
| Message-ID | <4F7215D1.3080208@verizon.net> |
| In reply to | #19087 |
On 03/27/2012 03:12 PM, Ben Bacarisse wrote: > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > >> Francois Grieu <fgrieu@gmail.com> writes: > <snip> >>> As an aside of the aside, I do not understand the third option in >>> the constraint, and it has been removed in N1570. >> >> It makes sense to remove it. > > No it didn't! This part of my reply was nonsense. It's perfectly > possible to well-define relative comparisons between pointers to > incomplete types. > > It's good to see that the change is just due to a change in terminology. Could you explain the change in terminology? I thought about the possibility that something like that was involved, but I didn't notice anything relevant.
[toc] | [prev] | [next] | [standalone]
| From | Harald van Dijk <haraldvdijk@gmail.com> |
|---|---|
| Date | 2012-03-27 12:47 -0700 |
| Message-ID | <8c95547a-d482-4404-b6fc-b2e909d7e130@k6g2000vbz.googlegroups.com> |
| In reply to | #19089 |
On Mar 27, 9:32 pm, James Kuyper <jameskuy...@verizon.net> wrote: > On 03/27/2012 03:12 PM, Ben Bacarisse wrote: > > It's good to see that the change is just due to a change in terminology. > > Could you explain the change in terminology? I thought about the > possibility that something like that was involved, but I didn't notice > anything relevant. I didn't notice it either, but as Tim Rentsch pointed out, the change is in 6.2.5p1. Old: "Types are partitioned into object types (types that fully describe objects), function types (types that describe functions), and incomplete types (types that describe objects but lack information needed to determine their sizes)." New: "Types are partitioned into object types (types that describe objects) and function types (types that describe functions)."
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-03-27 16:11 -0400 |
| Message-ID | <4F721F0B.2050701@verizon.net> |
| In reply to | #19090 |
On 03/27/2012 03:47 PM, Harald van Dijk wrote: > On Mar 27, 9:32 pm, James Kuyper <jameskuy...@verizon.net> wrote: >> On 03/27/2012 03:12 PM, Ben Bacarisse wrote: >>> It's good to see that the change is just due to a change in terminology. >> >> Could you explain the change in terminology? I thought about the >> possibility that something like that was involved, but I didn't notice >> anything relevant. > > I didn't notice it either, but as Tim Rentsch pointed out, the change > is in 6.2.5p1. Ah - that explains why I didn't know what Ben was talking about. I've got Tim killfiled - not because he's a spammer or any other kind of idiot, but just because I found that I frequently ended up wasting lots of time in long discussions with him disagreeing about excessively subtle issues without either of us ever managing to change the mind of the other. That would not have mattered if the discussions had been fun, or at least interesting, but I just found them frustrating - which could just as easily have been my fault as his.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-03-27 10:32 -0700 |
| Message-ID | <kfnr4wehruj.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #19072 |
Francois Grieu <fgrieu@gmail.com> writes:
> I just tested my code for portability problems on systems
> where int is 16-bit, and found one such system where
>
> #include <stdio.h>
> int main(void)
> {
> printf("%d\n", 0<(unsigned short)0x8000 );
> return 0;
> }
>
> outputs 0. If I change 0< to 0u<, the output is 1.
>
> Is that a bug in this compiler, w.r.t. C99?
Yes. There is a simple argument that it is:
1. The value 0x8000 is always representable as an unsigned short.
2. The rules for 'integer promotions' always preserve value.
3. The rules for 'usual arithmetic conversions' preserve value
for all operand values that are non-negative. (A negative
operand value might become non-negative due to UAC, but
all non-negative values don't change under UAC.)
Since 0 < 0x8000 must hold, 0 < (unsigned short) 0x8000 must hold,
because ultimately the same mathematical comparison is done.
> As an aside, 6.5.8p2 puzzles me; [snip]
>
> As an aside of the aside, I do not understand the third option in
> the constraint, and it has been removed in N1570.
The removal is not a change but just indicative of a change in
nomenclature. In C99, there are incomplete types and object
types. In N1570, there are incomplete object types and complete
object types, which together make up object types. So in N1570,
both complete and incomplete types are included under the now
more general 'object type' term, and hence the third option in
C99 is folded into the second option in N1570.
[toc] | [prev] | [next] | [standalone]
| From | Francois Grieu <fgrieu@gmail.com> |
|---|---|
| Date | 2012-03-28 15:08 +0200 |
| Message-ID | <4f730d57$0$21924$426a74cc@news.free.fr> |
| In reply to | #19080 |
On 27/03/2012 19:32, Tim Rentsch wrote:
> Francois Grieu <fgrieu@gmail.com> writes:
>
>> I just tested my code for portability problems on systems
>> where int is 16-bit, and found one such system where
>>
>> #include <stdio.h>
>> int main(void)
>> {
>> printf("%d\n", 0<(unsigned short)0x8000 );
>> return 0;
>> }
>>
>> outputs 0. If I change 0< to 0u<, the output is 1.
>>
>> Is that a bug in this compiler, w.r.t. C99?
>
> Yes. There is a simple argument that it is:
>
> 1. The value 0x8000 is always representable as an unsigned short.
>
> 2. The rules for 'integer promotions' always preserve value.
>
> 3. The rules for 'usual arithmetic conversions' preserve value
> for all operand values that are non-negative. (A negative
> operand value might become non-negative due to UAC, but
> all non-negative values don't change under UAC.)
>
> Since 0 < 0x8000 must hold, 0 < (unsigned short) 0x8000 must hold,
> because ultimately the same mathematical comparison is done.
Nice, reusable argument. Thanks.
>
>
>> As an aside, 6.5.8p2 puzzles me; [snip]
>>
>> As an aside of the aside, I do not understand the third option in
>> the constraint, and it has been removed in N1570.
>
> The removal is not a change but just indicative of a change in
> nomenclature. In C99, there are incomplete types and object
> types. In N1570, there are incomplete object types and complete
> object types, which together make up object types. So in N1570,
> both complete and incomplete types are included under the now
> more general 'object type' term, and hence the third option in
> C99 is folded into the second option in N1570.
Again, thanks for the synthetic explanation.
Francois Grieu
[toc] | [prev] | [next] | [standalone]
| From | Philipp Klaus Krause <pkk@spth.de> |
|---|---|
| Date | 2012-03-28 09:07 +0200 |
| Message-ID | <jkudbm$7vl$1@solani.org> |
| In reply to | #19072 |
On 27.03.2012 16:32, Francois Grieu wrote: > I just tested my code for portability problems on systems > where int is 16-bit, and found one such system where […] Which system? Philipp
[toc] | [prev] | [next] | [standalone]
| From | Francois Grieu <fgrieu@gmail.com> |
|---|---|
| Date | 2012-03-28 16:15 +0200 |
| Message-ID | <4f731d08$0$6475$426a74cc@news.free.fr> |
| In reply to | #19093 |
On 28/03/2012 09:07, Philipp Klaus Krause wrote: > On 27.03.2012 16:32, Francois Grieu wrote: >> I just tested my code for portability problems on systems >> where int is 16-bit, and found one such system where […] > > Which system? The CPU was a regular PC, running cmd.exe of Windows XP SP3; the failing compiler was Turbo C++ 1.01 (released 1991) in C mode. I am NOT using that compiler for anything but test. I there is a more modern 80x86 16-bit compiler (defined as UINT_MAX==0xFFFF, perhaps as an option), I want to know. My usual 16-bit targets include - ST7/ST19/ST21/ST23 - PIC18 - 8051 and derivatives and (at least with the compilers I now use for production) pass this test. My customer's platform include - 68K derivatives (including ColdFire) - ARM derivatives - MIPS derivatives - 80x86 derivatives For some of my customer's target systems, the option exist to compile with a 16-bit int (e.g. gcc -mshort ), and I have no idea of my customer's choice. Francois Grieu
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2012-03-28 14:26 +0000 |
| Message-ID | <20120328072320.731@kylheku.com> |
| In reply to | #19104 |
On 2012-03-28, Francois Grieu <fgrieu@gmail.com> wrote: > On 28/03/2012 09:07, Philipp Klaus Krause wrote: >> On 27.03.2012 16:32, Francois Grieu wrote: >>> I just tested my code for portability problems on systems >>> where int is 16-bit, and found one such system where […] >> >> Which system? > > The CPU was a regular PC, running cmd.exe of Windows XP SP3; the > failing compiler was Turbo C++ 1.01 (released 1991) in C mode. Hahaha, you wasted everyone's time answering questions about irrelevant old cruft. Good job!
[toc] | [prev] | [next] | [standalone]
| From | Peter Nilsson <airia@acay.com.au> |
|---|---|
| Date | 2012-03-27 23:22 -0700 |
| Message-ID | <46a76357-8752-4e50-9b1c-6e8047ba26fb@ur9g2000pbc.googlegroups.com> |
| In reply to | #19072 |
Francois Grieu <fgr...@gmail.com> wrote:
> I just tested my code for portability problems on systems
> where int is 16-bit, and found one such system where
>
> #include <stdio.h>
> int main(void)
> {
> printf("%d\n", 0<(unsigned short)0x8000 );
> return 0;
> }
>
> outputs 0. If I change 0< to 0u<, the output is 1.
>
> Is that a bug in this compiler, w.r.t. C99?
Impossible to tell. It's the wrong result, but it may
equally be explained by using an inappropriate library.
e.g. compiler is set to 16-bit ints, but the library
was compiled with 32-bit ints. It may even be that
components of the operating system that the library
relies on have changed.
[I used to swap between 16 and 32-bit platforms on the
old Apple Macs, and these sorts of issues happened!]
--
Peter
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web