public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* "Incompatible" typedefs
@ 2009-02-03 17:07 Charles Wilson
  2009-02-03 17:16 ` Christopher Faylor
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Charles Wilson @ 2009-02-03 17:07 UTC (permalink / raw)
  To: cygwin

I ran across an oddity in the cygwin headers today.

<machine/_types.h> has
typedef signed int __int32_t;
unsigned int __uint32_t;

<stdint.h> has
typedef long int32_t
typedef unsigned long uint32_t

<cygwin/types.h> has
typedef __uint32_t u_int32_t;

What this means is that these public types don't match (exactly)

uint32_t == unsigned long
u_int32_t == __uint32_t == unsigned int

Also, the public/private pair doesn't match (exactly)
int32_t == long
__int32_t == signed int


Now, on cygwin, there's no real harm. But from the C standard, long and
int are distinct types, so the following:

void func_a (u_int32_t * ptr) { ... stuff ... }
func_b (void)
{
  uint32_t x;
  func_a (&x);
}

raises a warning, without a typecast. But shouldn't "uint32_t" and
"u_int32_t" be identical in type, without requiring a typecast? (At
least in C. C++ is another story). If so, then what should be "fixed" in
the cygwin headers?  I'd bet stdint.h, since it is the odd man out --
but looking at its code it has a preference for "long" throughout. It
never uses "int". Plus, changing a fundamental typedef like this to
silence *my* warning, might cause thousands of other warnings from
existing code that expects &(unsigned long) to match &(uint32_t) without
a warning.

But my argument is, THAT client code is definitely non-portable to a
different platform where unsigned long might have a different number of
bits. But &(u_int32_t) ought to match &(uint32_t) without a warning on
ANY platform.

Or I could just add an explicit cast to my code, for the same reason.
<g>

--
Chuck

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "Incompatible" typedefs
  2009-02-03 17:07 "Incompatible" typedefs Charles Wilson
@ 2009-02-03 17:16 ` Christopher Faylor
  2009-02-04  8:26   ` Charles Wilson
  2009-02-03 18:24 ` Dave Korn
  2009-02-04  9:52 ` Corinna Vinschen
  2 siblings, 1 reply; 10+ messages in thread
From: Christopher Faylor @ 2009-02-03 17:16 UTC (permalink / raw)
  To: cygwin

On Tue, Feb 03, 2009 at 12:06:49PM -0500, Charles Wilson wrote:
>I ran across an oddity in the cygwin headers today.

This boils down to "What does linux do?".  If we are doing something
different then PTC.

cgf

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "Incompatible" typedefs
  2009-02-03 17:07 "Incompatible" typedefs Charles Wilson
  2009-02-03 17:16 ` Christopher Faylor
@ 2009-02-03 18:24 ` Dave Korn
  2009-02-04  9:52 ` Corinna Vinschen
  2 siblings, 0 replies; 10+ messages in thread
From: Dave Korn @ 2009-02-03 18:24 UTC (permalink / raw)
  To: cygwin

Charles Wilson wrote:
> I ran across an oddity in the cygwin headers today.

> <stdint.h> has
> typedef long int32_t
> typedef unsigned long uint32_t

> Now, on cygwin, there's no real harm. But from the C standard, long and
> int are distinct types, so the following:

   This is the 32-bit equivalent of the exact same problem that cause the 
template resolution failure that Marco and Tatsuro ran up against last week. 
I think we should probably add the missing 'int' to both 32- and 64-bit types. 
  Linux looks like it does it that way.

     cheers,
       DaveK

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "Incompatible" typedefs
  2009-02-03 17:16 ` Christopher Faylor
@ 2009-02-04  8:26   ` Charles Wilson
  2009-02-04 14:37     ` Dave Korn
  0 siblings, 1 reply; 10+ messages in thread
From: Charles Wilson @ 2009-02-04  8:26 UTC (permalink / raw)
  To: cygwin

Christopher Faylor wrote:
> On Tue, Feb 03, 2009 at 12:06:49PM -0500, Charles Wilson wrote:
>> I ran across an oddity in the cygwin headers today.
> 
> This boils down to "What does linux do?".  If we are doing something
> different then PTC.

Errr, it's a little weird. On linux, I have:

From <sys/types.h>
typedef unsigned int u_int8_t __attribute__ ((__mode__ (__QI__)));
typedef unsigned int u_int16_t __attribute__ ((__mode__ (__HI__)));
typedef unsigned int u_int32_t __attribute__ ((__mode__ (__SI__)));
typedef unsigned int u_int64_t __attribute__ ((__mode__ (__DI__)));

From <stdint.h>
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;

From <bits/types.h>
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;

So it looks like everything is defined in terms of ANSI C types (int,
char, etc) without the intermediation that cygwin's headers use. So, all
of the [__]u[_]int32_t types are all 'unsigned int'.

I'm guessing that "__attribute__ ((__mode__ (__SI__)))" doesn't make
u_int32_t different than uint32_t.  But apparently there is some heavy
duty compiler magic happening, because I would have thought that these two:

typedef unsigned int u_int16_t __attribute__ ((__mode__ (__HI__)));
typedef unsigned short int uint16_t;

are very different. But they are not (in that a variation of my test
case I posted earlier, emits no warnings with these two types).

I'm not sure what useful conclusions we can draw from looking at how
linux does it, Or maybe I just need some sleep.

--
Chuck

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "Incompatible" typedefs
  2009-02-03 17:07 "Incompatible" typedefs Charles Wilson
  2009-02-03 17:16 ` Christopher Faylor
  2009-02-03 18:24 ` Dave Korn
@ 2009-02-04  9:52 ` Corinna Vinschen
  2009-02-04 16:54   ` Charles Wilson
  2 siblings, 1 reply; 10+ messages in thread
From: Corinna Vinschen @ 2009-02-04  9:52 UTC (permalink / raw)
  To: cygwin

On Feb  3 12:06, Charles Wilson wrote:
> I ran across an oddity in the cygwin headers today.
> 
> <machine/_types.h> has
> typedef signed int __int32_t;
> unsigned int __uint32_t;
> 
> <stdint.h> has
> typedef long int32_t
> typedef unsigned long uint32_t
> 
> <cygwin/types.h> has
> typedef __uint32_t u_int32_t;
> 
> What this means is that these public types don't match (exactly)
> 
> uint32_t == unsigned long
> u_int32_t == __uint32_t == unsigned int
> 
> Also, the public/private pair doesn't match (exactly)
> int32_t == long
> __int32_t == signed int

This has been fixed in the 1.7 headers in May 2008.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "Incompatible" typedefs
  2009-02-04  8:26   ` Charles Wilson
@ 2009-02-04 14:37     ` Dave Korn
  2009-02-04 17:10       ` Charles Wilson
  0 siblings, 1 reply; 10+ messages in thread
From: Dave Korn @ 2009-02-04 14:37 UTC (permalink / raw)
  To: cygwin

Charles Wilson wrote:

> I would have thought that these two:
> 
> typedef unsigned int u_int16_t __attribute__ ((__mode__ (__HI__)));
> typedef unsigned short int uint16_t;
> 
> are very different. 

   I wouldn't have.  They're both unsigned, they're both integers, and they're 
both 16 bits.  HImode is the internal GCC type that gets mapped to C short 
ints.  Why do you think they would differ?

> I'm not sure what useful conclusions we can draw from looking at how
> linux does it, Or maybe I just need some sleep.

   I think we just add 'int' where it's missing from longs and long longs and 
we're done.  And there should be a handy test-case to reduce from the octave 
sources.

     cheers,
       DaveK




--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "Incompatible" typedefs
  2009-02-04  9:52 ` Corinna Vinschen
@ 2009-02-04 16:54   ` Charles Wilson
  0 siblings, 0 replies; 10+ messages in thread
From: Charles Wilson @ 2009-02-04 16:54 UTC (permalink / raw)
  To: cygwin

Corinna Vinschen wrote:

> This has been fixed in the 1.7 headers in May 2008.

You're right. I *thought* I was working in my 1.7 sandbox, but I was
actually in the 1.5 environment.

Sorry for the noise.

--
Chuck


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "Incompatible" typedefs
  2009-02-04 14:37     ` Dave Korn
@ 2009-02-04 17:10       ` Charles Wilson
  2009-02-04 18:46         ` Eric Blake
  0 siblings, 1 reply; 10+ messages in thread
From: Charles Wilson @ 2009-02-04 17:10 UTC (permalink / raw)
  To: cygwin

Dave Korn wrote:
> Charles Wilson wrote:
> 
>> I would have thought that these two:
>>
>> typedef unsigned int u_int16_t __attribute__ ((__mode__ (__HI__)));
>> typedef unsigned short int uint16_t;
>>
>> are very different. 
> 
>   I wouldn't have.  They're both unsigned, they're both integers, and
> they're both 16 bits.  HImode is the internal GCC type that gets mapped
> to C short ints.  Why do you think they would differ?

But on cygwin, unsigned long is unsigned, it is an integral type, and
both 'unsigned long' and 'unsigned int' are 32 bits. Under the hood,
they are identical.

But the compiler complained.

What you describe is exactly the "compiler magic" I was referring to:
"unsigned int __attribute__ ((__mode__ (__HI__)))" := unsigned short int
They "look different" but aren't.

>> I'm not sure what useful conclusions we can draw from looking at how
>> linux does it, Or maybe I just need some sleep.
> 
>   I think we just add 'int' where it's missing from longs and long longs
> and we're done.  And there should be a handy test-case to reduce from
> the octave sources.

As Corinna pointed out, this is moot. Fixed in 1.7.

But, at the risk of extending this thread -- I do have a question. Is
there really a difference between

short    vs.    short int
long     vs.    long int
unsigned vs.    unsigned int
signed   vs.    signed int
(etc, other combinations of modifiers with and without 'int')

Your argument seems to imply that there is. I always thought that the
'int' was implied when only the size (or signedness) was specified, and
that the types were exactly identical. No? Reference, please? Is this
buried in K&R somewhere I missed?

--
Chuck

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "Incompatible" typedefs
  2009-02-04 17:10       ` Charles Wilson
@ 2009-02-04 18:46         ` Eric Blake
  2009-02-05  0:07           ` Charles Wilson
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Blake @ 2009-02-04 18:46 UTC (permalink / raw)
  To: cygwin

Charles Wilson <cygwin <at> cwilson.fastmail.fm> writes:

> But, at the risk of extending this thread -- I do have a question. Is
> there really a difference between
> 
> short    vs.    short int
> long     vs.    long int
> unsigned vs.    unsigned int
> signed   vs.    signed int

No difference in any of those examples; however, I personally like the 
forms 'short int', 'long int', 'unsigned int', and 'int'.

> (etc, other combinations of modifiers with and without 'int')

The difference you are running into is the fact that 'int' and 'long int' (or 
alternately spelled, 'int' and 'long') are distinct types, even if they both 
occupy 32 bits and are both signed.  Likewise, 'unsigned long int' 
and 'unsigned int' (or alternately spelled, 'unsigned long' and 'unsigned') are 
distinct types, even if both occupy 32 bits and are both unsigned.  It is this 
difference that is tripping up 1.5 users, because the headers are using 
distinct types where they shouldn't be.  Also, 'signed int' and 'int' are 
identical, but 'char', 'unsigned char', and 'signed char' are three distinct 
types.

> Your argument seems to imply that there is. I always thought that the
> 'int' was implied when only the size (or signedness) was specified, and
> that the types were exactly identical. No? Reference, please?

How about C99 6.2.5 Types:

| There are five standard signed integer types, designated as signed char,
| short int, int, long int, and long long int. (These and other types may be
| designated in several additional ways, as described in 6.7.2.)

| For each of the signed integer types, there is a corresponding (but
| different) unsigned integer type (designated with the keyword unsigned)
| that uses the same amount of storage (including sign information) and has
| the same alignment requirements. The type _Bool and the unsigned integer
| types that correspond to the standard signed integer types are the standard
| unsigned integer types.

and 6.7.2 Type specifiers:

| Each list of type specifiers shall be one of the following sets (delimited
| by commas, when there is more than one set on a line); the type specifiers
| may occur in any order

| — char
| — signed char
| — unsigned char
| — short, signed short, short int, or signed short int
| — unsigned short, or unsigned short int
| — int, signed, or signed int
| — unsigned, or unsigned int
| — long, signed long, long int, or signed long int
| — unsigned long, or unsigned long int
| — long long, signed long long, long long int, or signed long long int
| — unsigned long long, or unsigned long long int

And with this knowledge, you then get to play with what gcc means by

>> typedef unsigned int u_int16_t __attribute__ ((__mode__ (__HI__)));
>> typedef unsigned short int uint16_t;

They are based on two different base types (unsigned int vs. unsigned short 
int), but the presence of __attribute__ means that you are outside the realm of 
C99, so it is up to the compiler whether u_int16_t is effectively the same 
class as 'unsigned short int' or whether it behaves more like an 'unsigned int' 
truncated to 16 bits.  And that's where I don't know the right answer.

-- 
Eric Blake




--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "Incompatible" typedefs
  2009-02-04 18:46         ` Eric Blake
@ 2009-02-05  0:07           ` Charles Wilson
  0 siblings, 0 replies; 10+ messages in thread
From: Charles Wilson @ 2009-02-05  0:07 UTC (permalink / raw)
  To: cygwin

Eric Blake wrote:
> The difference you are running into is the fact that 'int' and 'long int' (or 
> alternately spelled, 'int' and 'long') are distinct types, even if they both 
> occupy 32 bits and are both signed. 

Right. That was my understanding [*] which is why I assumed the cygwin
headers (in their 1.5 incarnation) needed some adjustment. But 1.7
already has the fix, so...

[*] "But on cygwin, unsigned long is unsigned, it is an integral
type,..." was my counterfactual argument against Dave's assertion that

typedef unsigned int u_int16_t __attribute__ ((__mode__ (__HI__)));
typedef unsigned short int uint16_t;

are somehow obviously identical. (They ARE identical, but it is
unobvious). Spellings matter. Except when they don't.

>> [Dave's argument elided]
>> Your argument seems to imply that there is. I always thought that the
>> 'int' was implied when only the size (or signedness) was specified, and
>> that the types were exactly identical. No? Reference, please?

> How about C99 6.2.5 Types:
[snipped]
> and 6.7.2 Type specifiers:
[snipped]

These both agree with my earlier understanding. But then I still don't
understand how Dave's "fix" would fix anything:

Changing:
typedef long int32_t
typedef unsigned long uint32_t

To:
typedef long int int32_t
typedef unsigned long int uint32_t

(e.g as Dave said, "just add 'int' where it's missing" -- that is, ADD,
 not replace)

is a case of changing the spelling without changing the meaning at all;
that change would have zero effect and the definition of uint32_t would
STILL be different than u_int32_t, an "unsigned int". Right?

> And with this knowledge, you then get to play with what gcc means by
> 
>>> typedef unsigned int u_int16_t __attribute__ ((__mode__ (__HI__)));
>>> typedef unsigned short int uint16_t;
> 
> They are based on two different base types (unsigned int vs. unsigned short 
> int), but the presence of __attribute__ means that you are outside the realm of 
> C99, so it is up to the compiler whether u_int16_t is effectively the same 
> class as 'unsigned short int' or whether it behaves more like an 'unsigned int' 
> truncated to 16 bits.  And that's where I don't know the right answer.

Yep. Deep dark compiler magic.

--
Chuck


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-02-05  0:07 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-03 17:07 "Incompatible" typedefs Charles Wilson
2009-02-03 17:16 ` Christopher Faylor
2009-02-04  8:26   ` Charles Wilson
2009-02-04 14:37     ` Dave Korn
2009-02-04 17:10       ` Charles Wilson
2009-02-04 18:46         ` Eric Blake
2009-02-05  0:07           ` Charles Wilson
2009-02-03 18:24 ` Dave Korn
2009-02-04  9:52 ` Corinna Vinschen
2009-02-04 16:54   ` Charles Wilson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).