Natural size: int

  • Thread starter Frederick Gotham
  • Start date
J

jacob navia

Al said:
For *some* Unix systems, perhaps.

On HP-UX, a long is still 32 bits.
Interesting...

What does gcc do in those systems?

It follows HP or remains compatible with itself?
 
K

Keith Thompson

Al Balmer said:
For *some* Unix systems, perhaps.

On HP-UX, a long is still 32 bits.

gcc has 32-bit longs on some systems, 64-bit longs on others. For the
most part, the division is between "32-bit systems" and "64-bit
systems", though neither phrase is particularly meaningful. I know
that some versions of HP-UX are 32-bit systems, so it wouldn't
surprise me to see 32-bit longs. If there are 64-bit versions of
HP-UX, I'd expect gcc to have 64-bit long on that system, though I
wouldn't depend on it.

I *think* that gcc typically has sizeof(long) == sizeof(void*). In
fact, all the systems I currently use, perhaps even all the systems
I've ever used, have sizeof(long)==sizeof(void*) (either 32 or 64
bits), though of course there's no requirement for them to be the same
size.
 
J

jacob navia

Keith said:
gcc has 32-bit longs on some systems, 64-bit longs on others. For the
most part, the division is between "32-bit systems" and "64-bit
systems", though neither phrase is particularly meaningful. I know
that some versions of HP-UX are 32-bit systems, so it wouldn't
surprise me to see 32-bit longs. If there are 64-bit versions of
HP-UX, I'd expect gcc to have 64-bit long on that system, though I
wouldn't depend on it.

I *think* that gcc typically has sizeof(long) == sizeof(void*). In
fact, all the systems I currently use, perhaps even all the systems
I've ever used, have sizeof(long)==sizeof(void*) (either 32 or 64
bits), though of course there's no requirement for them to be the same
size.

That's a VERY wise decision.

Microsoft's decision of making sizeof(long) < sizeof(void *)
meant a LOT OF WORK at a customer's site recently. It was a basic
assumption of thir code.
 
I

Ian Collins

jacob said:
Microsoft disagrees... :)
My comment was based on my experience with Sparc, I'm sure LP64 was
adopted as the 64 bit ABI (mainly to support mixed 32 and 64
applications IIRC) before gcc had a 64 bit Sparc port.

A bit OT, but can you mix 32 and 64 bit applications on 64 bit windows?
I have to follow the lead compiler in each system. By the way, the
lead compiler in an operating system is the compiler that compiled
the Operating System: MSVC under windows, gcc under linux, etc.
You have to, if you want to link with the system libraries!
 
A

Al Balmer

Interesting...

What does gcc do in those systems?

It follows HP or remains compatible with itself?

It follows HP, naturally. It even uses HP libraries. On HP-UX
Integrity, it's a decent compiler, but can't yet produce optimized
code for the Itanium processor.

I find the idea of a compiler remaining "compatible with itself" to be
rather odd.
 
J

jacob navia

Ian said:
My comment was based on my experience with Sparc, I'm sure LP64 was
adopted as the 64 bit ABI (mainly to support mixed 32 and 64
applications IIRC) before gcc had a 64 bit Sparc port.

A bit OT, but can you mix 32 and 64 bit applications on 64 bit windows?

No. You can't load a 32 bit DLL (shared object) from a 64 bit
process. Of course you can use system() to call a 32 bit
application but that is another process that runs in the 32 bit
emulation layer.
You have to, if you want to link with the system libraries!
Yes, that's the reason.
 
H

Hallvard B Furuseth

jacob said:
For unix systems, gcc decided that
char 8, short 16, int 32, long 64, long long 64

gcc decided to do whatever the system was already doing to the best of
its ability, so that gcc-compiled code could be used with existing
libraries (like the C library:) It contains a lot of code to figure
that out.

If it didn't, nobody would have used it. Remember, gcc is older than
Linux & co. When the GNU project was started, Unixes were full of
proprietary closed-source libraries - and there are still plenty of them
around, on systems where gcc is in use.
 
A

Ancient_Hacker

The funny thing is this issue was partly solved in 1958, 1964, and in
1971.

In 1958 Grace Hopper and Co. designed COBOL so you could actually
declare variables and their allowed range of values! IIRC something
like:

001 DECLARE MYPAY PACKED-DECIMAL PICTURE "999999999999V999"
001 DECLARE MYPAY USAGE IS COMPUTATIONAL-/1/2/3

Miracle! A variable with predictable and reliable bounds! Zounds!


But this still isnt quite the ticket, you can only specify decimal
numbers to arbitrary and dependable precision, floating-point numbers
are still a hodge-podge.

Then in 1964 PL/I (may it rest in peace) tried to combine COBOL and
Fortran and Algol, with mixed results. But they did extend
declarations to make variable declarations a bit better, so you could
specify, separately, decimal or binary math, and the number of decimal
places before and after the decimal point:

dcl J fixed binary (7);
dcl K fixed bin (8) unsigned;
dcl L fixed bin (15);
dcl M fixed bin;
dcl N fixed bin (31);
dcl O fixed bin (31,16);
dcl S fixed dec (7,2);

Still not quite the ticket.


Then in 1971 Pascal went in a slightly different direction, but not far
enough, by letting you specify explicit variable bounds, but only for
integer and scalar (enum) types:

var Year: 1900..3000;

------

What the typical user REALLY needs, and may not be doable in any simple
or portable way, is a wide choice of what one wants:

Case (1): I need an integer that can represent the part numbers in a
1996 Yugo, well known to range from 0 to 12754. Pascal leads the way
here: var PartNumber: 0..12754.

Case (2): I need a real that can represent the age of the universe, in
Planck units, about 3.4E-42 to 12.E84. The accuracy of measurement is
only plus or minus 20 percent, so two significant digits is plenty.
PL/I is the only language I know of that can adequately declare this:
DECLARE AGE FLOAT BINARY (2,85). Which hopefully the compiler will map
to whatever floating-point format can handle that exponent.

case (3): I need an integer that can do exact math with decimal prices
from 0.01 to 999,999,999,99. COBOL and PL/I can do this.

case (4): I need a 32-bit integer. Pascal and PL/I are the only
languages that can do this: var I32: -$7FFFFFFF..$7FFFFFFF; PL/I:
DECLARE I32 FIXED BINARY (32).

case (5): I need whatever integer format is fastest on this CPU and
is at least 32 bits wide. Don't know of any language that has this
capability.

------------------------

<soap>
I think it's high time a language has the ability to do the very basic
and simple things programmers need to write portable software: the
ability to specify, unambiguously, what range of values they need to
represent, preferably in decimal, binary, floating, fixed, and even
arbitrary bignum formats. Not to mention hardware-dependent perhaps
bit widths. There's no need for the compiler to be able to actually
*do* any arbitrarily difficult arithmetic, but at least give the
programmer the ability to ASK and if the compiler is capable, and get
DEPENDABLE math. I don't think this is asking too much.

The biness of C having wink-wink recognized defacto binary integer
widths is IMHO just way below contempt. The way was shown many
different times since 1958, why can't we get something usable, portable
and reasonable now quite a ways into the 21st century?


</soap>
 
R

Richard

Ancient_Hacker said:
<soap>
I think it's high time a language has the ability to do the very basic
and simple things programmers need to write portable software: the
ability to specify, unambiguously, what range of values they need to
represent, preferably in decimal, binary, floating, fixed, and even
arbitrary bignum formats. Not to mention hardware-dependent perhaps
bit widths. There's no need for the compiler to be able to actually
*do* any arbitrarily difficult arithmetic, but at least give the
programmer the ability to ASK and if the compiler is capable, and get
DEPENDABLE math. I don't think this is asking too much.

It is if you want the system to perform.

But than ADA does all that you want and more.

And its not usually the compiler that does any arithmetic : its normally
runtime bounds checks. Can be very time consuming. And one reason why C
doesnt do it. C isnt about things like that.
 
R

Richard Bos

Ancient_Hacker said:
The biness of C having wink-wink recognized defacto binary integer
widths is IMHO just way below contempt. The way was shown many
different times since 1958, why can't we get something usable, portable
and reasonable now quite a ways into the 21st century?

Darling, if you want Ada, you know where to find her.

Richard
 
C

Clark S. Cox III

That's a VERY wise decision.

Microsoft's decision of making sizeof(long) < sizeof(void *)
meant a LOT OF WORK at a customer's site recently. It was a basic
assumption of thir code.

Well, it could be argued that it was a good decision as it helped to
expose flaws in their code.
 
D

Dik T. Winter

> Case (1): I need an integer that can represent the part numbers in a
> 1996 Yugo, well known to range from 0 to 12754. Pascal leads the way
> here: var PartNumber: 0..12754.

type PartNumber is range 0 .. 12754;
> Case (2): I need a real that can represent the age of the universe, in
> Planck units, about 3.4E-42 to 12.E84. The accuracy of measurement is
> only plus or minus 20 percent, so two significant digits is plenty.
> PL/I is the only language I know of that can adequately declare this:
> DECLARE AGE FLOAT BINARY (2,85). Which hopefully the compiler will map
> to whatever floating-point format can handle that exponent.

type Age is digits 2 range 3.4E-42 .. 12.0E84;
> case (3): I need an integer that can do exact math with decimal prices
> from 0.01 to 999,999,999,99. COBOL and PL/I can do this.

type Amount is delta 0.01 range 0.01 .. 999_999_999.99;
> case (4): I need a 32-bit integer. Pascal and PL/I are the only
> languages that can do this: var I32: -$7FFFFFFF..$7FFFFFFF; PL/I:
> DECLARE I32 FIXED BINARY (32).

type I32 is range -16#7FFFFFFF .. 16#7FFFFFFF;
> case (5): I need whatever integer format is fastest on this CPU and
> is at least 32 bits wide. Don't know of any language that has this
> capability.

Long_Integer

(If it is defined of course, if not, there probably are no 32 bit wide
integers available. But if it is defined, it is at least 32 bits wide.)

This all in Ada.
 
R

Richard Bos

jacob navia said:
That's a VERY wise decision.

Why? Whatever good does it do? Don't tell me you have the beginner's
habit of casting void *s back and forth to integers...
Microsoft's decision of making sizeof(long) < sizeof(void *)
meant a LOT OF WORK at a customer's site recently. It was a basic
assumption of thir code.

It is a very, very unwise assumption - as you experienced.

Richard
 
A

Ancient_Hacker

Richard said:
Darling, if you want Ada, you know where to find her.

Richard

!! ewwww. yuck. Somehow after I took one look at Ada, I just put it
out of my mind. I think a lot of people did that. Maybe when there's
a open source Ada compiler that generates good code and doesnt give me
the feeling I'm writing a cruise-missle guidance program..
 
S

Skarmander

jacob said:
Interesting...

What does gcc do in those systems?

It follows HP or remains compatible with itself?

gcc is retargetable; it has multiple backends. Your question makes no sense.
gcc doesn't make specific assumptions and then looks for platforms with
which it's compatible; gcc is ported by adapting the backend to the platform.

If it didn't, it would be a whole lot less portable, and a whole lot less
useful.

S.
 
K

Keith Thompson

Ancient_Hacker said:
!! ewwww. yuck. Somehow after I took one look at Ada, I just put it
out of my mind. I think a lot of people did that. Maybe when there's
a open source Ada compiler that generates good code and doesnt give me
the feeling I'm writing a cruise-missle guidance program..

<OT>
There is an open source Ada compiler; it's called GNAT, and it's part
of gcc. Nobody can do anything about how you feel when you're writing
code, though.

You complain that no one language provides a set of features. When
someone mentions one that does, you reaction is "ewwww. yuck." Hmm.
</OT>
 
S

Skarmander

Ancient_Hacker said:
The funny thing is this issue was partly solved in 1958, 1964, and in
1971.

In 1958 Grace Hopper and Co. designed COBOL so you could actually
declare variables and their allowed range of values! IIRC something
like:

001 DECLARE MYPAY PACKED-DECIMAL PICTURE "999999999999V999"
001 DECLARE MYPAY USAGE IS COMPUTATIONAL-/1/2/3

Miracle! A variable with predictable and reliable bounds! Zounds!
COBOL more than made up for its innovative and genuinely useful approach to
type declarations with its innovative and genuinely horrendous approaches to
syntax, control flow and type conversions. That said, it's good to remember
the ways in which COBOL didn't suck.

What the typical user REALLY needs, and may not be doable in any simple
or portable way, is a wide choice of what one wants:
Well, it's still a C group, so let's look at how far our language of
topicality gets us.
Case (1): I need an integer that can represent the part numbers in a
1996 Yugo, well known to range from 0 to 12754. Pascal leads the way
here: var PartNumber: 0..12754.
Although C offers less flexibility and safety in this regard, an adequate
approximation is to use the smallest type guaranteed to contain your range.
In this case, "short" (or "int" if time is of more concern than space, since
"int" is intended to be more "natural" to the platform).

You can use a typedef to abstract away from the actual type and convey the
purpose to humans, but C does not allow true subtyping, so you'd have to do
any range checks yourself. This obviously encourages a style where these
checks are done as little as possible, or possibly never, which is a clear
drawback.
Case (2): I need a real that can represent the age of the universe, in
Planck units, about 3.4E-42 to 12.E84. The accuracy of measurement is
only plus or minus 20 percent, so two significant digits is plenty.
PL/I is the only language I know of that can adequately declare this:
DECLARE AGE FLOAT BINARY (2,85). Which hopefully the compiler will map
to whatever floating-point format can handle that exponent.
And which will hopefully not introduce any glaring rounding or accuracy
errors when involved in calculations with other floating-point types. That
the language offers this is neat, but in order to use these types
effectively special attention is required, which reduces the advantage over
not having these types natively and having to think about the calculations
from the beginning.
case (3): I need an integer that can do exact math with decimal prices
from 0.01 to 999,999,999,99. COBOL and PL/I can do this.
C cannot do this natively, so you'll need libraries. Luckily, C also makes
it possible to implement such libraries efficiently. This is a good way of
highlighting the differences in philosophy.
case (4): I need a 32-bit integer. Pascal and PL/I are the only
languages that can do this: var I32: -$7FFFFFFF..$7FFFFFFF; PL/I:
DECLARE I32 FIXED BINARY (32).
You can do this in C, but only if your platform actually provides a native
integer type of exactly 32 bits. Then #include <stdint.h> and use int32_t.
If your platform doesn't have <stdint.h>, porting won't be for free, but not
exactly involved either.

This boils down to the question of *why* you need a 32-bit integer. Do you
absolutely, positively, have to have an integral type that takes up exactly
32 bits, or else your algorithm will simply fail or be inapplicable? Then
int32_t is exactly what you mean.

If you'd merely like an integer type with range
[-2,147,483,647;2,147,483,647] which may use more bits if this is
convenient, then you're back to case (1), and for C "long" will do the
trick. Again, range checking you will have to handle yourself.
case (5): I need whatever integer format is fastest on this CPU and
is at least 32 bits wide. Don't know of any language that has this
capability.
That's odd, because this is just one of those things C was practically made
to do. I should think C's "long" will get you as close as possible. Or
#include <stdint.h> and use int_fast32_t to emphasize "fastest". In any
case, if such an integer format exists at all, you will surely find it
implemented in the platform's C compilers.

The biness of C having wink-wink recognized defacto binary integer
widths is IMHO just way below contempt.

You're doing the language a disservice by describing it this way. C has
well-defined constraints on its integer types, designed to allow a broad
range of platforms to provide integer calculations in a way most suited to
that platform. It's true that this shifts the burden to the programmer in a
way that may be considered inappropriate for many applications, but it's
certainly not "wink-wink" or "de facto" -- and who cares if it started out
this way?

"De facto" assumptions are the reason programmers get the worst of both
worlds: C leaves the types relatively unconstrained to promote portability,
yet (poor) programmers will assume that the integer types will be identical
across platforms. You can prefer one or the other, but shouldn't be
expecting the opposite of what you actually have and be dismayed by the results.
<soap>
I think it's high time a language has the ability to do the very basic
and simple things programmers need to write portable software:

The one thing programmers need to write portable software is a good grasp of
the ways in which different computer systems are equal, and the ways in
which they are different, and the ways in which this might matter to your
specific program. No individual language will confer such insight.
the ability to specify, unambiguously, what range of values they need to
represent, preferably in decimal, binary, floating, fixed, and even
arbitrary bignum formats. Not to mention hardware-dependent perhaps bit
widths. There's no need for the compiler to be able to actually *do*
any arbitrarily difficult arithmetic, but at least give the programmer
the ability to ASK and if the compiler is capable, and get DEPENDABLE
math. I don't think this is asking too much.

If there's no need for the compiler to be able to do what you ask, then how
is your program portable? You're asking for a system that implements what
you want it to implement, or else your program will not run on it. This is
portability by demanding the system be suitable for your program, rather
than the other way around.

All programming languages are a compromise between allowing the programmer
to write down exactly what they want and allowing the programmer to write
down that which is effectively translatable and executable. You can take
individual languages to task for making the wrong compromises for your
purposes, but taking them to task for compromising at all is slightly
disingenuous.

As others have mentioned, Ada goes a long way towards implementing the
numerical paradise you envision. Of course, Ada has its own problems.
The way was shown many different times since 1958, why can't we get
something usable, portable and reasonable now quite a ways into the 21st
century?
Reasonability is in the eye of the beholder, but anyone who would deny C's
usability or portability, even when only restricted to numerical types, is
being deliberately obtuse.

If you're asking in general how languages are created and adopted, and why
the Right Language always seems to lose to the Right Now Language, that's
quite another topic.

S.
 
A

Al Balmer

You can use a typedef to abstract away from the actual type and convey the
purpose to humans, but C does not allow true subtyping, so you'd have to do
any range checks yourself. This obviously encourages a style where these
checks are done as little as possible, or possibly never, which is a clear
drawback.

Perhaps, but it also allows a style where such checks are done only
when necessary.
 
S

Stephen Sprunk

jacob navia said:
Microsoft disagrees... :)

MS also disagrees with C standard (and hundreds of other standards)
compliance; they're hardly an authority unless your only goal is to be
compatible with their stuff.

IL32LLP64 makes sense when either (a) 32-bit ops are faster than
64-bit ones, or (b) you know the vast majority of the codebase assumes
longs are only 32-bit. Both apply to MS's target market for their
compiler and OS; they don't apply to the general UNIX world.
I am not saying that gcc's decision is bad, I am just stating this
as
a fact without any value judgement. Gcc is by far the most widely
used compiler under Unix, and they decided LP64, what probably is
a good decision for them.

I'm sure whoever came up with the Linux ABI consulted the GCC folks,
but such things are primarily determined by the OS developers, not the
compiler developers. If the compiler doesn't follow the OS API, it's
close to useless.
I have to follow the lead compiler in each system. By the way, the
lead compiler in an operating system is the compiler that compiled
the Operating System: MSVC under windows, gcc under linux, etc.

You're making distinctions where they aren't needed. Each platform
has an official ABI (or two), and that ABI is determined jointly by
the compiler folks and the OS folks. If you weren't included in that
discussion, all you can do is follow the ABI that they specified.

Heck, that's the position GCC is in on most platforms, and they have a
hell of a lot more influence than you do.

S
 
M

Malcolm

Stephen Sprunk said:
Do you really care so much about the extra two or three letters it takes
to use a type that is _guaranteed_ to work that you're willing to accept
your program randomly breaking?
Yes. If we just have one variable in scope, a bit of gibberish at the start
and end of the type is neither here nor there.
But if we've got several in scope, and we need another gibberish prefix like
xlu_ to represent the library we're using, and another gibberish suffix like
U8 because someone has insisted on that notation, and the code is littered
with gibberish casts and gibberish comments, and gibberish constructs like
for(;;) and "123 = xlu_i_U8;" then the gibberish accumulates, and suddenly
you find youself in the situation where the code is no longer readable.
 

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

Forum statistics

Threads
473,754
Messages
2,569,525
Members
44,997
Latest member
mileyka

Latest Threads

Top