Sizes of Integer Types

F

Flash Gordon

Richard Heathfield wrote, On 12/09/07 09:21:
Ian Collins said:


Yes, of course. C99 makes it not only possible but easy to write such
code. Not only does the use of C99 features render your code
non-portable to C90 implementations, but it can even render your code
non-portable to *other C99 implementations*.

Yes, but if you know this and have good reasons this is not a problem
just a known limitation.
This is true of C90, too, but in a much more limited way. For example, I
have occasionally had cause to define an array of UCHAR_MAX + 1
unsigned long ints, which seems perfectly unobjectionable and indeed is
quite okay on what you might call "normal" implementations - but on
reflection it's easy to see how it could break. If CHAR_BIT is 32, say,
then that array is suddenly rather on the large side.

I've worked on systems where CHAR_BIT is 16 and the processor has a 16
bit address bus and some of the address space allocated by the processor
manufacturer for special purposes. So your array is *guaranteed* not to fit.
So one must exercise care even in C90 (or accept that one's code is not
portable to certain kinds of implementation). C99 has all of the C90
portability issues, and adds a whole bunch of new ones.

So you are allowed to ignore the portability issues that do not affect
you but those who have different portability requirements are not
allowed to limit themselves to the implementations of interest to you?

I've had very good reasons to limit myself to implementations which
support a 16 bit integer type with no padding, and at the time I *knew*
that there were implementations with no type smaller than 24 bits. My
employer would not have been pleased if I spent extra time making it
portable to implementations it was *very* unlikely to be ported to.
 
F

Flash Gordon

Kelsey Bjarnason wrote, On 12/09/07 17:40:
[snips]

The lack of portability is imposed by the requirement to use a type
that's exactly 32 bits.

Which means you've already limited your compiler choice,
Yes.

which means you
already know the sizes involved

You do not know *which* type will be the required width, or you may be
targeting multiple implementations which have a 32 bit type, but on each
implementation it is a *different* one of the base types.
which means _at most_ using a typedef of
your own to achieve exactly what's needed - 32 bit ints on this one, 32
bit longs on that one. The new int types are simply not needed here.

The types make it a lot simpler and less error prone since you don't
need to construct the mess of conditional defines and try to find a way
to prove that it will always select the correct type if it exist or
cause a compilation failure if it does not.
So, we're agreed, in this case, the int types are a complete waste of
paper.

No, you keep asserting that other peoples reasons for using them don't
count.

I *could* write the entire program in machine code with a hex editor so
we don't need C at all so C is a complete waste. That is the argument
you are making.
Yet this is, apparently, the only time you can rely on them. So
we're agreed; they're useless.

No, you assert that because for your purposes they are of no use. That
does not mean that others cannot have different requirements.
Because uint32_t et al are broken beyond redemption and must be avoided at
all costs. Yes, we're agreed.

Is your code portable to all systems? Can I run ALL of your code on the
card I used to program for with 16 bit char, short and int, 8K of ROM
for the program and 8K of RAM for the data?
Use a typedef; it's pretty trivial and people have been doing it for what,
30 years?

Oh, I see. The new int types are intended to accomplish something already
done by long practice, but accomplish it in such a way that code relying
on the new approach falls on its face just because you change platforms,
is that what you're saying?

The old approach would fail on implementations without a type of the
required type. It would either fail by allowing the code to compile on a
platform where it will NOT work or it will fail (by your definition)
because it does not compile.
No thanks, I'll stick with what works - and
the new int types ain't it.

Don't use them. Those for whom they *are* the correct types, who do not
need to port to all possible implementations, will use them secure in
the knowledge that they provide exactly the correct functionality.
 
R

Richard Heathfield

Flash Gordon said:
Richard Heathfield wrote, On 12/09/07 09:21:

Yes, but if you know this and have good reasons this is not a problem
just a known limitation.

As long as it is a *known* limitation, it is not a problem.
I've worked on systems where CHAR_BIT is 16 and the processor has a 16
bit address bus and some of the address space allocated by the
processor manufacturer for special purposes. So your array is
*guaranteed* not to fit.

Yes, absolutely. My point entirely.
So you are allowed to ignore the portability issues that do not affect
you but those who have different portability requirements are not
allowed to limit themselves to the implementations of interest to you?

ITYM s/to you/to them/

Of course they are. I freely accept that there may be legitimate reasons
for using intN_t - but there /is/ a portability cost, and that needs to
be made very clear. Naturally, those who are prepared to pay that cost
can expect to reap the perceived benefits.

<snip>
 
A

Al Balmer

Which means you've already limited your compiler choice, which means you
already know the sizes involved which means _at most_ using a typedef of
your own to achieve exactly what's needed - 32 bit ints on this one, 32
bit longs on that one. The new int types are simply not needed here.

Why do I have to worry about "this one" and "that one"? If I use the
uint32_t, I let the compiler worry about it.

Which is more portable among implementations that have a 32-bit int
type, no matter what it's called? My uint32_t, or your "let's read the
documentation and change the code"?

As to being limited by implementation choice, of course that's true.
The very fact that I require an exact 32-bit int has already limited
my choice. No matter whether I use one name for the type, or your
method of one name per implementation.
 
I

Ian Collins

Kelsey said:
[snips]

If your code is processing a stream of say 16 bit data, you can either
assume the existence of a 16 (or 8) bit type

Like char and short? Oh, they're not required to be 8 and 16 bits, just
at least 8 and 16 bits. Meaning we've had perfectly good types for this
sort of thing since what, K&R?
So what would you rather have, code using short that compiles happily on
a system where short is 32 or 18 bits, but then fails to work (possibly
in a less than obvious way) or code that uses int16_t and won't compile?

I for one would prefer the latter.
 
K

Kelsey Bjarnason

[snips]

Then why quote form a document that may or may not be correct.

Because I *do* have that handy, I *don't* have the other handy.

Either use the standard or don't. Don't use something that may or may
not be right but tries to pretend it has some authority.

Fine. In future, I'll refer to such things as "being pulled from Chris
Hills' rectal orifice" so there will be no confusion. Happy now?
 
I

Ian Collins

Kelsey said:
[snips]

Nonsense, I wouldn't call PPC or SPARC "close equivalents" to x86.

The code will work as intended on a system with, oh, 32 bit chars?
Whoops, nope. As I said, it'll work on an x86 and a few close equivalents.
That's gone from nonsense to total bollocks. Kindly show how PPC or
SPARC are "close equivalents" to x86.
No more masking to ensure there's only 8 value bits (or 16, or 32) in use.
No more sucking up 32 bits where an 8 bit value is wanted. Even if these
types incurred a speed overhead by emulating the types, chances are it
would be worth it.

Enter uint8_t. Perfect. Just what the doctor ordered. Let's use it.
Except we can't, because it isn't even required to exist.
As I said before, if the system does have a native 8 bit type, just add
the typedef, if not, you can't use it. The existence of the C99
typedefs changes nothing in this regard.
 
A

Al Balmer

Chris Hills said:
Kelsey Bjarnason said:
[snips]

On Thu, 06 Sep 2007 11:51:57 -0700, Keith Thompson wrote:

If you just want integer types of specified sizes, take a look at
the <stdint.h> header, which defines int8_t, int16_t, etc.

My copy of the draft says
Your copy of the draft is irrelevant.

It is a DRAFT if you are going to mess around with the compiler you
need the standard itself. NOT a draft.

Is it your contention that the final Standard differs from the draft in
this regard? Specifically, Kelsey said: "My copy of the draft says that
intN_t types are optional, an implementation is not required to provide
them." As far as I'm aware, this remains true in the final Standard. I
refer you specifically to 7.18(4): "An implementation shall provide
those types described as ``required'', but need not provide any of the
others (described as ``optional'')."
Yes, but that is not what Kelsey said. What he said disagrees with my
copy of the C99 standard (and my copy of the 9899:TC2 draft.)

Certain of the stdint types are required, and others are required *if*
the implementation is able to provide them. For example, for the exact
width types:

7.18.1.1(3)
"These types are optional. However, if an implementation provides
integer types with widths of 8, 16, 32, or 64 bits, no padding bits,
and (for the signed types) that have a two’s complement
representation, it shall define the corresponding typedef names."

and for the minimum-width types,
7.18.1.2(3)
"The following types are required:
int_least8_t
int_least16_t
int_least32_t
int_least64_t
uint_least8_t
uint_least16_t
uint_least32_t
uint_least64_t
All other types of this form are optional."
 
R

Richard Heathfield

Al Balmer said:
Yes, but that is not what Kelsey said. What he said disagrees with my
copy of the C99 standard (and my copy of the 9899:TC2 draft.)

Fine - but that's a different argument. My beef with Chris is that he's
saying the draft is meaningless *even though it agrees with the
Standard*.
Certain of the stdint types are required, and others are required *if*
the implementation is able to provide them. For example, for the exact
width types:

7.18.1.1(3)
"These types are optional. However, if an implementation provides
integer types with widths of 8, 16, 32, or 64 bits, no padding bits,
and (for the signed types) that have a two’s complement
representation, it shall define the corresponding typedef names."

ISO/IEC 9899:1999 reads:

3 These types are optional. However, if an implementation provides
integer types with widths of 8, 16, 32, or 64 bits, it shall define the
corresponding typedef names.

n869.txt reads:

[#3] These types are optional. However, if an |
implementation provides integer types with widths of 8, 16, |
32, or 64 bits, it shall define the corresponding typedef |
names.

Word for word the same.

<snip>
 
I

Ian Collins

Richard said:
Fine - but that's a different argument. My beef with Chris is that he's
saying the draft is meaningless *even though it agrees with the
Standard*.
To be able to make that statement, you have to have a copy of the
standard to compare, having that copy would make the draft redundant, if
not meaningless.
 
J

jacob navia

Kelsey said:
Fine. In future, I'll refer to such things as "being pulled from Chris
Hills' rectal orifice" so there will be no confusion. Happy now?

Have you maybe noticed that USENET is not the toilet?

Next time, when you feel like insulting people this way
maybe you go to the toilet instead of posting stuff?

Mr Hills neither insulted you, nor was in ANY WAY offensive.
He took issue of you using a draft and not the standard itself,
a minor objection.

Your answer is of such disproportionate baseness that
only reveals what you really are.
 
A

Al Balmer

Fine - but that's a different argument.

Agreed. I just didn't want him to think he got away with it said:
My beef with Chris is that he's
saying the draft is meaningless *even though it agrees with the
Standard*.

I don't know where I read it, but I think the draft is simply a
compilation of the original C99 and the TCs, and errata. As such, it
includes the current standard.

Ah, here we go:
"The lastest (sic) publically (sic) available version of the standard
is the combined C99 + TC1 + TC2, WG14 N1124, dated 2005-05-06. This is
a WG14 working paper, but it reflects the consolidated standard at the
time of issue."
http://www.open-std.org/jtc1/sc22/wg14/www/standards

That's why I never worried about differences in the draft. I own a
copy of C99, but I use the draft, because it includes the TCs.
 
A

Al Balmer

To be able to make that statement, you have to have a copy of the
standard to compare, having that copy would make the draft redundant, if
not meaningless.

Not at all. The draft is useful because it combines ISO/IEC 9899:1999
and the Technical Corrigenda in one easily searchable document.
 
A

A N Other

Have you maybe noticed that USENET is not the toilet?

You say that, but plenty of people fill it with shit. Spam about
lcc-win32 for example.
Next time, when you feel like insulting people this way
maybe you go to the toilet instead of posting stuff?

Mr Hills neither insulted you, nor was in ANY WAY offensive.
He took issue of you using a draft and not the standard itself,
a minor objection.

Your answer is of such disproportionate baseness that
only reveals what you really are.

Rubbish. Chris Hills behaved like a complete idiot.
 
R

Richard Heathfield

Ian Collins said:
To be able to make that statement, you have to have a copy of the
standard to compare,

And I do.
having that copy would make the draft redundant,

No, it's not redundant. If I didn't have it, I wouldn't be able to make
the comparison.
if not meaningless.

The only meaningless bits are the bits that did not make it into the
final Standard.
 
K

Kelsey Bjarnason

Kelsey said:
[snips]

If your code is processing a stream of say 16 bit data, you can either
assume the existence of a 16 (or 8) bit type

Like char and short? Oh, they're not required to be 8 and 16 bits, just
at least 8 and 16 bits. Meaning we've had perfectly good types for this
sort of thing since what, K&R?
So what would you rather have, code using short that compiles happily on
a system where short is 32 or 18 bits, but then fails to work (possibly
in a less than obvious way) or code that uses int16_t and won't compile?

I'd rather have code that compiles and works. Maybe that means masking,
fine, I can live with that if I have to. At least I'd only have one code
path to maintain, and it would work on _any_ conforming implementation.
 
K

Kelsey Bjarnason

[snips]

That's gone from nonsense to total bollocks. Kindly show how PPC or
SPARC are "close equivalents" to x86.

Already did. Pay attention.
As I said before, if the system does have a native 8 bit type, just add
the typedef, if not, you can't use it. The existence of the C99
typedefs changes nothing in this regard.

Unless you use them, at which point your code's portability has gone
straight into the crapper. Yay, C! Yesterday you were portable across
endless systems, now you're portable across... well... who the hell knows,
because all bets are off. An absolute *leap* ahead, right into the 16th
century.

Gah.
 
K

Kelsey Bjarnason

[snips]

Ok, show me how to write a typedef for a signed type that's exactly 32
bits wide, with no padding bits and a 2's-complement representation,
so that I don't have to change the definition for different platforms.

Oh, wait, somebody's already done that for you; it's called uint32_t.

Good. Show me where this is defined on a machine with 64-bit types.
Whoops. Doesn't exist. Next.
 
K

Kelsey Bjarnason

[snips]

Then please show us your typedef for a type of *exactly* 32 bits on a
system with 9-bit char, 18-bit short, 36-bit int and long and 72-bit
long long.

And your uint32_t exists on a machine with 64-bit types, right?

Nope. Next.
 
C

Charlie Gordon

Harald van D?k said:
Kelsey said:
[snips]

If you just want integer types of specified sizes, take a look at the
<stdint.h> header, which defines int8_t, int16_t, etc.

My copy of the draft says that intN_t types are optional, an
implementation is not required to provide them. As such, it strikes me
that code cannot rely on them unless one gives up portability across
compilers, never mind OSen.

Has this changed, or is this still little more than a good way to
guarantee you're stuck using one vendor's compiler for the rest of
eternity?

int8_t, int16_t, int32_t, int64_t and the corresponding unsigned integer
types are required on systems where there exist types matching the
descriptions. This means that on C99 implementations where they're not
defined, it wouldn't be possible to use some other type as a substitute
anyway, unless you didn't really need an exact-width integer type in the
first place.

It would have been good to mandate their support on _all_ architectures.
Odd bit sized and non 2's complement machines could emulate them in
software...
Such biests are disappearing fast at this time, and lack of complete c99
support for them would not have hurt anybody.

Definitely something to remember for the next release.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top