code portability

K

Keith Thompson

Richard Heathfield said:
Keith Thompson said:


Indeed. So is this:

char 8 bits
short 64 bits
int 64 bits
long 64 bits

and at least one implementation does it like that.


Er, and?

Er, and I've worked on such a system, and it caused some real
problems. There was a 16-bit or 32-bit field in an externally imposed
data format. The relevant system header declared it as a bit field.
Code that assumed you could take the address of that field broke.

The C compiler could have created 16-bit and 32-bit integer types,
using the same convoluted mechanism it used to handle 8-bit types --
but if these types had been called "short" and "int", then a lot of
code would have used them and become unreasonably slow as a result.

In C99, I suppose the system could have defined them as extended
integer types, guaranteeing that they wouldn't be used unless you
explicitly asked for them. Then intfast32_t would be 64 bits, but
int32_t would be 32 bits (and slow).

That's a problem with the design of <stdint.h>; the naming scheme
assumes that exact-width types are more important than types with *at
least* a specified size or range.
 
R

Richard Heathfield

Keith Thompson said:
Er, and I've worked on such a system, and it caused some real
problems. There was a 16-bit or 32-bit field in an externally imposed
data format. The relevant system header declared it as a bit field.
Code that assumed you could take the address of that field broke.

Bit-fields are broken anyway. I'd read it a byte at a time, and copy the
bits over "by hand", so to speak.
 
K

Keith Thompson

Richard Heathfield said:
Keith Thompson said:

Bit-fields are broken anyway. I'd read it a byte at a time, and copy the
bits over "by hand", so to speak.

Yes, that's another (equally inconvenient) approach. But in any case
I didn't have the option of modifying the system header files.
 
A

Andrew Poelstra

That's true, but 64 bits is the effective limit for this. The
following:
char 8 bits
short 16 bits
int 32 bits
long 64 bits
is a reasonable set of types, but if you go beyond that to 128 bits,
you're going to have to leave gaps (for example, there might not be
any 16-bit integer type).

1) This isn't really a problem; you can use a 32-bit variable to store
16-bit values; if you really need 16 bits you might need some debug
macros to artificially constrain the range.
2) If you've got a 128-bit processor, IMHO, you shouldn't be insisting
on using 8-bit types. That just sounds inefficient. [OT]
 
I

Ian Collins

Keith said:
My objection to C's integer type system is that the names are
arbitrary: "char", "short", "int", "long", "long long", "ginormous
long". I'd like to see a system where the type names follow a regular
pattern, and if you want to have a dozen distinct types the names are
clear and obvious. I have a few ideas, but since this will never
happen in any language called "C" I won't go into any more detail.
Isn't that why we now have (u)int32_t and friends? I tend to use int or
unsigned if I don't care about the size and one of the exact size type
if I do.
 
I

Ian Collins

Andrew said:
1) This isn't really a problem; you can use a 32-bit variable to store
16-bit values; if you really need 16 bits you might need some debug
macros to artificially constrain the range.

Just beware of overflows!
2) If you've got a 128-bit processor, IMHO, you shouldn't be insisting
on using 8-bit types. That just sounds inefficient. [OT]
Unless your (possibly externally imposed) data happens to be 8 bit.
 
L

lawrence.jones

Richard Heathfield said:
The introduction of long long int was, in my continued opinion, a mistake.
All the ISO guys had to do was - nothing at all! Any implementation that
wanted to support 64-bit integers could simply have made long int rather
longer than before - such a system would have continued to be fully
conforming to C90. And if it broke code, well, so what? Any code that
wrongly assumes long int is precisely 32 bits is already broken, and needs
fixing.

The problem was not breaking code but breaking binary compatibility.
Lots of vendors wanted to add 64 bit support to their existing 32 bit
platforms (for large file support, if nothing else), but they couldn't
very well change the size of long on the existing platforms without
breaking *everything*. The expedient, if not elegant, solution was long
long. Most of the committee didn't really like the idea, but it was
already a common extension and promised to become more so, so we figured
we'd better standardize it (particularly the promotion rules) so that
people had a chance of using it portably.

-Larry Jones

Fortunately, that was our plan from the start. -- Calvin
 
L

lawrence.jones

Keith Thompson said:
My objection to C's integer type system is that the names are
arbitrary: "char", "short", "int", "long", "long long", "ginormous
long". I'd like to see a system where the type names follow a regular
pattern, and if you want to have a dozen distinct types the names are
clear and obvious.

Well, one wag did propose adding the "very" keyword to C so that,
instead of long long we could have very long (and very very long, and
very very very long, etc.), not to mention very short (and very very
short, etc.). You could even have very const....

-Larry Jones

I hope Mom and Dad didn't rent out my room. -- Calvin
 
B

Bill Pursell

Andrew Poelstra wrote:

2) If you've got a 128-bit processor, IMHO, you shouldn't be insisting
on using 8-bit types. That just sounds inefficient. [OT]

Kind of an ironic statement in a thread about portability. :)
 
K

Keith Thompson

Andrew Poelstra said:
1) This isn't really a problem; you can use a 32-bit variable to store
16-bit values; if you really need 16 bits you might need some debug
macros to artificially constrain the range.

Yes, this was really a problem. The issue wasn't just the range, it
was the representation of an externally imposed data format.
2) If you've got a 128-bit processor, IMHO, you shouldn't be insisting
on using 8-bit types. That just sounds inefficient. [OT]

Unless, of course, you're doing string processing.
 
A

Andrew Poelstra

Just beware of overflows!

Yes, that would require more than debug macros to fix, since you'd want
the overflow behavior to be the same whether or not you are debugging!
(It's a bit of a pain, I admit, but there aren't too many times when you
absolutely need an exact number of bits.)
2) If you've got a 128-bit processor, IMHO, you shouldn't be insisting
on using 8-bit types. That just sounds inefficient. [OT]
Unless your (possibly externally imposed) data happens to be 8 bit.

If I were ISO, I'd consider adding a new specifier to scanf and friends
to read a specified number of bytes (or probably bits, although that
could be a lot harder to implement) into an already defined type. So, if
you wanted to read 8 bits into an int (which is 32 bits on this particular
system), you'd do:
fscanf (fhandle, "%d8b", &charvar);

Since I'm not ISO, nor will they create such a change, I'd stick to
avoiding arbitrary data widths (in general, stick with text files as
long as you can spare the space), and don't worry about changing data
widths: most companies don't switch compilers too often.

If you have Data of a Certain Width imposed on you, you're probably
going to have to fiddle with stuff when changing compilers anyway,
so suddenly having long twice as wide should be an expected problem.
 
M

Michael Mair

Richard said:
Keith Thompson said:

Indeed. And, on a related note, I find it very difficult to understand this
fascination with integers that have a particular number of bits. If I need
8 bits, I'll use char (or a flavour thereof). If I need 9 to 16 bits, I'll
use int (or unsigned). If I need 17 to 32 bits, I'll use long (or unsigned
long). And if I need more than 32 bits, I'll use a bit array. I see
absolutely no need for int_leastthis, int_fastthat, and int_exacttheother.

Depends on your area of application.
If you are in an embedded environment with two's complement, exact
width integers of width 8, 16, 32, you often want the 16 bit type
because it is sufficient for storing your data and saves memory
you really need. Even if it is only provided as compiler extension.
You compute values "through overflow" to save auxiliary variables
and time and do other things not necessary when in a less restricted
environment.

For other applications, I agree with you. However, I _would_ have
liked to have a clean naming scheme implying what the standard
says instead of nondescript identifiers.
short <-> int_least16_t
int <-> int_fast16_t
long <-> int_least32_t
obviously does not give that in a convenient manner. int16, int32,
intFast16, intExact16 probably would have been a better starting
point for easy extensibility.


Cheers
Michael
 
J

jacob navia

Richard Heathfield a écrit :
The introduction of long long int was, in my continued opinion, a mistake.
All the ISO guys had to do was - nothing at all! Any implementation that
wanted to support 64-bit integers could simply have made long int rather
longer than before - such a system would have continued to be fully
conforming to C90. And if it broke code, well, so what? Any code that
wrongly assumes long int is precisely 32 bits is already broken, and needs
fixing.

So what if it is broken? I wouldn't want to fix it. Let it run as it was
till now.

Leave long as it was and use a new type for 64 bits. This was the
decision of Microsoft.

Gcc decided otherwise. Long becomes 64 bits, and long long stays 64
bits, making this type completely useless.

For lcc-win64 I thought about

char 8 bits
short 16 bits
int 32 bits
long 64 bits
long long 128 bits

but then... I would have been incompatible
to both: gcc AND MSVC.

So I decided to follow MSVC under windows-64 and gcc
under unix-64.
 
R

Richard

Andrew Poelstra said:
Yes, that would require more than debug macros to fix, since you'd want
the overflow behavior to be the same whether or not you are debugging!
(It's a bit of a pain, I admit, but there aren't too many times when you
absolutely need an exact number of bits.)

Its not the fact that you absolutley *must* have the bits, rather than
the fact you want defined, repeatable behaviour.

The simplest test condition in the world would be hugely concerned to
knwo that that programmer didnt care if it was 16 or 32 bits

if(!x=func(y))
...;

How many times this would really be a problem I wouldnt venture to say.
 
F

Frederick Gotham

Ian Collins posted:
Isn't that why we now have (u)int32_t and friends? I tend to use int or
unsigned if I don't care about the size and one of the exact size type
if I do.


I use "int unsigned" when I want to store a positive integer.

I use "int signed" when the integer value might be negative.

If the unsigned number might exceed 65535, or if the signed number might
not fit in the range +32767 to -32767, then I'll consider using "int long
unsigned" or "int long signed", or perhaps "int long long unsigned" or "int
long long signed".

I only use "plain" char when I'm dealing with characters.

I only use "unsigned char" when I'm playing with bytes.

I've never used "short", but I'd consider using it if I had a large array
of integers whose value wouldn't exceed 65535.
 
S

Stephen Sprunk

Well, one wag did propose adding the "very" keyword to C so that,
instead of long long we could have very long (and very very long,
and
very very very long, etc.), not to mention very short (and very very
short, etc.). You could even have very const....

Don't forget very NULL:

http://thedailywtf.com/forums/thread/71684.aspx

I do have to wonder what "very unsigned" or "very int" would mean...

S
 
B

Ben Pfaff

Richard said:
Its not the fact that you absolutley *must* have the bits, rather than
the fact you want defined, repeatable behaviour.

The simplest test condition in the world would be hugely concerned to
knwo that that programmer didnt care if it was 16 or 32 bits

if(!x=func(y))
...;

Why should I care whether func() returns 16 or 32 bits? I only
want to know whether it returned a nonzero value, and the
specific value, be it 1 or 2 or -5 or 0xffffffff, doesn't matter.

(That won't compile, by the way. You forgot a set of parentheses.)
 
R

Richard

Ben Pfaff said:
Why should I care whether func() returns 16 or 32 bits? I only
want to know whether it returned a nonzero value, and the
specific value, be it 1 or 2 or -5 or 0xffffffff, doesn't matter.

because 0x10000 wont be zero since 32 bits hold it. 16 bits
will cycle through 0. Or?
 
B

Ben Pfaff

Richard said:
because 0x10000 wont be zero since 32 bits hold it. 16 bits
will cycle through 0. Or?

func() should return the proper type for its caller to interpret
it? If it doesn't, then the caller is not going to be able to
interpret correctly. If it does, then the condition makes sense
regardless of the type.
 
G

Guest

Ben said:
func() should return the proper type for its caller to interpret
it? If it doesn't, then the caller is not going to be able to
interpret correctly. If it does, then the condition makes sense
regardless of the type.

!(x=func(y)) doesn't test func's return value. It tests func's return
value converted to the type of x. If x is narrower than func(), even
nonzero return values may cause the expression to evaluate to 1.

char ch; while((ch = getchar()) != EOF) { /* ... */ }
 

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,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top