* newbie question about integers size/portabilty.
@ 2004-12-28 12:29 Ribamar Santarosa de Sousa
2004-12-28 13:35 ` Richard Cooper
0 siblings, 1 reply; 10+ messages in thread
From: Ribamar Santarosa de Sousa @ 2004-12-28 12:29 UTC (permalink / raw)
To: linux-assembly
Hi all,
(about this question is about C programming, i think the
"assemblers-guys" are most likely to answers quickly than not so
advanced c programmers.... :)
in the c style guide:
http://www.psgd.org/paul/docs/cstyle/cstyle16.htm
we can found a table (shown bellow) for integer data sizes.
there we can se that some architecture have more than one possible
value for the same size, depending on -- i guess -- the compiler.
Does anyone know where i can get a accurate table for gcc compiler?
Can those values change from a processor in the x86 to another with
fixed-size word (e.g. 486 -> 586)? (The document provides a "safe
minimal size" table, but note, as i am mixing several integer types
to pass to a hardware data structure, this is not enough, i need
exact values).
TIA, Riba.
type pdp11 VAX/11 68000 Cray-2 Unisys Harris 80386
series family 1100 H800
_________________________________________________________________
char 8 8 8 8 9 8 8
short 16 16 8/16 64(32) 18 24 8/16
int 16 32 16/32 64(32) 36 24 16/32
long 32 32 32 64 36 48 32
char* 16 32 32 64 72 24 16/32/48
int* 16 32 32 64(24) 72 24 16/32/48
int(*)() 16 32 32 64 576 24 16/32/48
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: newbie question about integers size/portabilty.
2004-12-28 12:29 newbie question about integers size/portabilty Ribamar Santarosa de Sousa
@ 2004-12-28 13:35 ` Richard Cooper
2004-12-28 15:20 ` Ribamar Santarosa de Sousa
2004-12-28 22:38 ` Brian Raiter
0 siblings, 2 replies; 10+ messages in thread
From: Richard Cooper @ 2004-12-28 13:35 UTC (permalink / raw)
To: linux-assembly
> (about this question is about C programming, i think the
> "assemblers-guys" are most likely to answers quickly than not so
> advanced c programmers.... :)
I don't know, I think C programmers have to deal with this crap all the
time, so they'd probably be more likely to know. I know that crap like
this is why I program in assembly. No one can solve the problem of how to
make data types portable when one system doesn't have the same sizes as
another, so someone says "hey, let's just make four sizes, char, short,
int and long, and be completely undecided and nonspecific about them,
thereby passing the problem on to the programmer so that we don't have to
deal with it" and that was that. Nevermind that every programmer will
have to deal with it, since if char isn't at least 7 bits then they need
to make their strings out of shorts instead of chars. Wonderful idea
there.
I myself would have made sizes like "1bit" and "2bit" and "3bit" and
"4bit" all the way up to "1000bit" and said that if you need at least 11
bits in your number, use "11bit" and it'll compile into a data size at
least large enough to hold 11 bit numbers. But that would have made far
too much sense.
But enough with my ranting...
I seem to recall seeing macros in C code like sizeof(int) used to figure
out the size of things and then conditionally compile code. Though I have
no idea how it works, I would test sizeof(whatever) until I found one
that's large enough, then define some word like "bits16" to whatever data
type turns out to be that size or larger, and then use "bits16" when
declaring variables instead of "int" or "long" or any of those.
Something like this:
if sizeof(char) >= 16
define bits16 char
elseif sizeof(short) >= 16
define bits16 short
elseif sizeof(int) >= 16
define bits16 int
elseif sizeof(long) >= 16
define bits16 long
else
scream "you can't compile this program because your system sucks"
endif
Just repeat it for "bits1" through "bits32" or whatever you plan to go up
to, and there you go. Then in your program instead of doing "int varible"
do "bits16 variable" and things will work pretty much how they should have
be done in the first place.
> Does anyone know where i can get a accurate table for gcc compiler?
I think that char is 8, short is 16, long is 32, and int I think is also
32. I'm pretty sure. That's the values I use when I have to convert
those stupid size names in C structures into something that actually
exists, and it seems to always work.
> i am mixing several integer types to pass to a hardware data structure,
> this is not enough, i need exact values.
Oh, well, then, if you're doing something hardware specific, I suppose you
can say to heck with the portability aspect. So just use char for 8,
short for 16, and int for 32 and be done with it.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: newbie question about integers size/portabilty.
2004-12-28 13:35 ` Richard Cooper
@ 2004-12-28 15:20 ` Ribamar Santarosa de Sousa
2004-12-30 9:10 ` Frederic Marmond
2004-12-28 22:38 ` Brian Raiter
1 sibling, 1 reply; 10+ messages in thread
From: Ribamar Santarosa de Sousa @ 2004-12-28 15:20 UTC (permalink / raw)
To: Richard Cooper; +Cc: linux-assembly
> > Does anyone know where i can get a accurate table for gcc compiler?
>
> I think that char is 8, short is 16, long is 32, and int I think is also
> 32. I'm pretty sure. That's the values I use when I have to convert
> those stupid size names in C structures into something that actually
> exists, and it seems to always work.
>
> > i am mixing several integer types to pass to a hardware data structure,
> > this is not enough, i need exact values.
>
> Oh, well, then, if you're doing something hardware specific, I suppose you
> can say to heck with the portability aspect. So just use char for 8,
> short for 16, and int for 32 and be done with it.
Thanks for the funny approach... Now i'm convinced that the above values
for integers must work... Just to let you know i can't say to heck the
portability aspect because i am porting the module, so the hell is where
I am :)
Contented, Riba.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: newbie question about integers size/portabilty.
2004-12-28 13:35 ` Richard Cooper
2004-12-28 15:20 ` Ribamar Santarosa de Sousa
@ 2004-12-28 22:38 ` Brian Raiter
2004-12-28 23:52 ` Ribamar Santarosa de Sousa
2004-12-29 7:21 ` OT: " Richard Cooper
1 sibling, 2 replies; 10+ messages in thread
From: Brian Raiter @ 2004-12-28 22:38 UTC (permalink / raw)
To: linux-assembly
> No one can solve the problem of how to make data types portable when
> one system doesn't have the same sizes as another, so someone says
> "hey, let's just make four sizes, char, short, int and long, and be
> completely undecided and nonspecific about them, thereby passing the
> problem on to the programmer so that we don't have to deal with it"
> and that was that.
This rather misses the point, I think.
At the time C was written, most computer languages either specified a
precise size for their integer types, or more likely they were
designed to only run on one platform and nobody gave a second thought
to portability. So you'd have a situation where "int" was specified as
always being *exactly* 16 bits, for example, because that's the best
size for integers on the hardware that exists at the time your
language was created. Which means that your compiled program would run
like a sick dog when compiled on a modern P4 machine, which has
atrocious handling of 16-bit math.
The C language specifies that a C int should be set to the platform's
"native" integer size -- whatever is going to be the fastest and most
versatile. 32 bits on a 32-bit machine, 64 bits on a 64-bit machine,
18 bits on an 18-bit machine.
> Nevermind that every programmer will have to deal with it, since if
> char isn't at least 7 bits then they need to make their strings out
> of shorts instead of chars.
This is untrue. The ANSI C standard specifies minimum guaranteed
sizes. chars have to be able to hold at least 8 bits, shorts and ints
both have to be able to hold at least 16 bits, longs at least 32 bits,
and long longs at least 64 bits. Thus we can see that it's actually
not possible to write a C compiler for an 8-bit microprocessor that is
both well-optimized and ANSI-compliant. (Embedded 8-bit software is
typically written using a C compiler that's about 90% compliant.)
> I myself would have made sizes like "1bit" and "2bit" and "3bit" and
> "4bit" all the way up to "1000bit" and said that if you need at
> least 11 bits in your number, use "11bit" and it'll compile into a
> data size at least large enough to hold 11 bit numbers.
... thereby passing the problem of what integer size will produce
efficient code on to the programmer, so that you don't have to deal
with it.
> I seem to recall seeing macros in C code like sizeof(int) used to
> figure out the size of things and then conditionally compile code.
sizeof isn't a macro, actually, and it cannot be used to conditionally
compile code. For most cases, you can simply rely on the guaranteed
sizes I mentioned above. If you're dealing with circumstances in which
you really need to know EXACT sizes, then your best option is to use
the macros in <limits.h>. In this header file are defined macros such
as CHAR_BIT, INT_MIN, ULONG_MAX, etc etc etc.
http://www-ccs.ucsd.edu/c/limits.html shows what the ANSI C standard
defines. (POSIX defines a number of other macros to be included.)
If you know that you're using a C99-compliant compiler, then you can
look at <stdint.h> and perhaps use the types defined there. However,
C99 compilers are not particular widespread at this time.
b
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: newbie question about integers size/portabilty.
2004-12-28 22:38 ` Brian Raiter
@ 2004-12-28 23:52 ` Ribamar Santarosa de Sousa
2004-12-29 0:17 ` Brian Raiter
2004-12-29 7:21 ` OT: " Richard Cooper
1 sibling, 1 reply; 10+ messages in thread
From: Ribamar Santarosa de Sousa @ 2004-12-28 23:52 UTC (permalink / raw)
To: Brian Raiter; +Cc: linux-assembly
> > I seem to recall seeing macros in C code like sizeof(int) used to
> > figure out the size of things and then conditionally compile code.
>
> sizeof isn't a macro, actually, and it cannot be used to conditionally
> compile code. For most cases, you can simply rely on the guaranteed
> sizes I mentioned above. If you're dealing with circumstances in which
> you really need to know EXACT sizes, then your best option is to use
> the macros in <limits.h>. In this header file are defined macros such
> as CHAR_BIT, INT_MIN, ULONG_MAX, etc etc etc.
> http://www-ccs.ucsd.edu/c/limits.html shows what the ANSI C standard
> defines. (POSIX defines a number of other macros to be included.)
>
I really needed of documentation on data syzes and no code would save me
because i don't have all the machines
that the code could work. The code was written with (i guess) not with the
best pratices in this point, it uses int, short , long instead the data
types defined in linux/types.h (__u16, __s8, ...)... I am making these
changes and in the future no one will need worry about size of data
structures.
And thanks Brian for the corrections on some points touched by Cooper :)
Riba
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: newbie question about integers size/portabilty.
2004-12-28 23:52 ` Ribamar Santarosa de Sousa
@ 2004-12-29 0:17 ` Brian Raiter
2004-12-29 1:05 ` Ribamar Santarosa de Sousa
0 siblings, 1 reply; 10+ messages in thread
From: Brian Raiter @ 2004-12-29 0:17 UTC (permalink / raw)
To: Ribamar Santarosa de Sousa; +Cc: linux-assembly
> I really needed of documentation on data syzes and no code would
> save me because i don't have all the machines that the code could
> work.
Which is exactly why you need to use code to determine the sizes.
Documentation won't help because the sizes are free to change over
time, with new versions of the OS and/or the compiler.
> The code was written with (i guess) not with the best pratices in
> this point, it uses int, short , long instead the data types defined
> in linux/types.h (__u16, __s8, ...)...
Using the types defined in <linux/types.h> will make your code
unportable. They aren't even guaranteed to be present in future
versions of Linux.
If you need a type that is at least 16 bits in size, use short or
int. If you need a type that is exactly 16 bits in size (no more or
less), then use conditional compilation with the macros in <limits.h>.
For example:
#if USHRT_MAX == 0xFFFF
typedef unsigned short u16;
#elif UINT_MAX == 0xFFFF
typedef unsigned int u16;
#else
#error "Platform lacks an integer type that is exactly 16 bits."
#endif
If you don't care about portability, then why bring this up in the
first place?
b
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: newbie question about integers size/portabilty.
2004-12-29 0:17 ` Brian Raiter
@ 2004-12-29 1:05 ` Ribamar Santarosa de Sousa
2004-12-29 1:31 ` Herbert Poetzl
0 siblings, 1 reply; 10+ messages in thread
From: Ribamar Santarosa de Sousa @ 2004-12-29 1:05 UTC (permalink / raw)
To: Brian Raiter; +Cc: Ribamar Santarosa de Sousa, linux-assembly
>
> Which is exactly why you need to use code to determine the sizes.
> Documentation won't help because the sizes are free to change over
> time, with new versions of the OS and/or the compiler.
>
We're talking about 2 differents things...
*yes, i need the codes to warranty portability in timeline (you meant
this, i didn't meant this)
*i don't have the machine the code was written for the first
time, so i don't know what authors meant when defining a structure
having an int member: 16, 32, 64 bits? code doesn't help in this case (i
suppose :).
...But don't care about this...
>
> Using the types defined in <linux/types.h> will make your code
> unportable. They aren't even guaranteed to be present in future
> versions of Linux.
>
... living and learning... i didn't know this... i thought this types
are defined for ensure i will have a unsigned 16 bit whenever i need a
unsigned 16 bit structure...
> If you need a type that is at least 16 bits in size, use short or
> int. If you need a type that is exactly 16 bits in size (no more or
> less), then use conditional compilation with the macros in <limits.h>.
> For example:
>
> #if USHRT_MAX == 0xFFFF
> typedef unsigned short u16;
> #elif UINT_MAX == 0xFFFF
> typedef unsigned int u16;
> #else
> #error "Platform lacks an integer type that is exactly 16 bits."
> #endif
>
i will use this... thanks...
> If you don't care about portability, then why bring this up in the
> first place?
>
i do care!
Thanks,
Riba
> b
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: newbie question about integers size/portabilty.
2004-12-29 1:05 ` Ribamar Santarosa de Sousa
@ 2004-12-29 1:31 ` Herbert Poetzl
0 siblings, 0 replies; 10+ messages in thread
From: Herbert Poetzl @ 2004-12-29 1:31 UTC (permalink / raw)
To: Ribamar Santarosa de Sousa; +Cc: Brian Raiter, linux-assembly
On Tue, Dec 28, 2004 at 11:05:58PM -0200, Ribamar Santarosa de Sousa wrote:
> >
> > Which is exactly why you need to use code to determine the sizes.
> > Documentation won't help because the sizes are free to change over
> > time, with new versions of the OS and/or the compiler.
> >
>
> We're talking about 2 differents things...
> *yes, i need the codes to warranty portability in timeline (you meant
> this, i didn't meant this)
> *i don't have the machine the code was written for the first
> time, so i don't know what authors meant when defining a structure
> having an int member: 16, 32, 64 bits? code doesn't help in this case (i
> suppose :).
> ...But don't care about this...
>
> >
> > Using the types defined in <linux/types.h> will make your code
> > unportable. They aren't even guaranteed to be present in future
> > versions of Linux.
> >
>
> ... living and learning... i didn't know this... i thought this types
> are defined for ensure i will have a unsigned 16 bit whenever i need a
> unsigned 16 bit structure...
yes, that is exactly the purpose of those types
(as is with C99 stdint.h types like uint16_t
and friends)
> > If you need a type that is at least 16 bits in size, use short or
> > int. If you need a type that is exactly 16 bits in size (no more or
> > less), then use conditional compilation with the macros in <limits.h>.
> > For example:
> >
> > #if USHRT_MAX == 0xFFFF
> > typedef unsigned short u16;
> > #elif UINT_MAX == 0xFFFF
> > typedef unsigned int u16;
> > #else
> > #error "Platform lacks an integer type that is exactly 16 bits."
> > #endif
>
> i will use this... thanks...
if you are coding for the linux-kernel, then
I would use the __u/sXX or u/sXX types ...
best,
Herbert
> > If you don't care about portability, then why bring this up in the
> > first place?
> >
>
> i do care!
>
> Thanks,
> Riba
>
> > b
> -
> To unsubscribe from this list: send the line "unsubscribe linux-assembly" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread
* OT: Re: newbie question about integers size/portabilty.
2004-12-28 22:38 ` Brian Raiter
2004-12-28 23:52 ` Ribamar Santarosa de Sousa
@ 2004-12-29 7:21 ` Richard Cooper
1 sibling, 0 replies; 10+ messages in thread
From: Richard Cooper @ 2004-12-29 7:21 UTC (permalink / raw)
To: linux-assembly
If anyone's annoyed by offtopic discussions, I've got a perfectly good web
board that's being used for nothing at the moment that we can move this to
(assuming it goes any further). It's at:
http://www.xersedefixion.com/forum/
However, I doubt anyone cares, so I'll assume that's the case until
someone tells us to shut up, but I'll go ahead and post a copy of this
there as well in case everyone else knows differently.
> This rather misses the point, I think.
It may very well, as it's simply how things currently appear to me.
> This is untrue. The ANSI C standard specifies minimum guaranteed
> sizes. chars have to be able to hold at least 8 bits, shorts and ints
> both have to be able to hold at least 16 bits, longs at least 32 bits,
> and long longs at least 64 bits.
Now that's much more useful for getting code written, but totally useless
for porting to machines with different data type sizes.
It sounds fine from the perspective of eight-bits-to-the-byte computing,
but go down to seven-bits-to-the-byte and it looks completely silly, as
your chars will contain 6 more bits than you're allowed to use, your
shorts will probably contain 12 more bits than you're allowed to use, and
your longs will contain 24 extra bits. Go up to nine-bits-to-the-byte and
it's not quite as bad as that, but then you still have bits you're not
allowed to use because they aren't there when compiled on an
eight-bits-to-the-byte system. So to stay compliant you have to pretend
like you have an eight-bits-to-the-byte system, and if you're willing to
do that to be portable, then why have those extra bits in your system at
all? Why not just go buy an eight-bits-to-the-byte system? It makes
sense I suppose in C context where the entire premise of portability is
mearly coding to the lowest common denominator, but it's not what I would
consider a workable solution to the problem.
>> I myself would have made sizes like "1bit" and "2bit" and "3bit" and
>> "4bit" all the way up to "1000bit" and said that if you need at
>> least 11 bits in your number, use "11bit" and it'll compile into a
>> data size at least large enough to hold 11 bit numbers.
> ... thereby passing the problem of what integer size will produce
> efficient code on to the programmer, so that you don't have to deal
> with it.
No, it wasn't something I even considered. But now that I have, it only
took me a few seconds to think of something better than ANSI C's hack of a
solution.
Just have two sets of those data types, one for when you want the smallest
type available, and another for when you want the fastest type available.
Something like char1 through char99 for things like characters where
you're just looking for small storage size, which always translate to the
smallest size available, and another set like int1 through int99 for when
you're looking for something you can make fast calculations with, which
always translate to the machine's word size, except for the cases where it
doesn't have enough bits, in which case it translates to something
less-optimal yet sufficient.
Then if you write your code for a 36 bit machine, where you can use
"int36" and make full use of all 36 bits without having to think about
eight-bits-to-the-byte systems since on those machines it will compile
into a 64 bit number. Then you can use "int17" for other numbers which
are smaller, but for which you still want your machine's 36 bit number for
speed reasons, and they'll compile into 32 bit numbers on
eight-bits-to-the-byte systems. Now that is portable, whereas making the
programmer go through their code and change all of their data types isn't,
and making a programmer pretend like their 36 bit machine is a 32 bit
machine is just plain dumb.
Am I mistaken that the goal is to have code that compiles without
modification on different architectures? I don't see how C as it is can
do that without forcing less-than-optimial code on those other
architectures. Either people with 36 bit systems use only 32 bits, or
they go and change half of their "ints" to "long longs" when they want to
compile their code on a different system. If you consider languages where
it's only portable if someone "ports" the code, then by that definition
every language is portable, and so including all of this nonsense for
portability is just a waste of time since someone will have to go in and
change all of the data type sizes anyway.
It seems to me like the goal is simply to be silly. It's portability by
appearance only. You can't totally disregard bit sizes and end up with a
solution that works, and ANSI C's standard of "lets just pretend everyone
has eight-bits-to-the-byte systems" is still disregarding bit sizes, just
in a way that works just fine for people with eight-bits-to-the-byte
systems.
I really think some people have it stuck in their head that all that's
needed to be done to create portability is to pretend like bits don't
exist, and then everything will magically work because nothing depends on
data type sizes. But everything depends on data type sizes, and so you
can't just ignore the bits.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: newbie question about integers size/portabilty.
2004-12-28 15:20 ` Ribamar Santarosa de Sousa
@ 2004-12-30 9:10 ` Frederic Marmond
0 siblings, 0 replies; 10+ messages in thread
From: Frederic Marmond @ 2004-12-30 9:10 UTC (permalink / raw)
To: Ribamar Santarosa de Sousa; +Cc: Richard Cooper, linux-assembly
some sizeof, depending of the architecture:
on a 32 bits system:
float=4
double=8
long double=12
char=1
short=2
short int=2
int=4
long=4
long int=4
long long=8
long long int=8
char*=4
on a 64 bits system
float=4
double=8
long double=16
char=1
short=2
short int=2
int=4
long=8
long int=8
long long=8
long long int=8
char*=8
note that 'long' may make your types change (long double, long, ...) according
to the architecture.
pointeurs are also affected.
Fred
Selon Ribamar Santarosa de Sousa <ribamar.sousa@ic.unicamp.br>:
> > > Does anyone know where i can get a accurate table for gcc compiler?
> >
> > I think that char is 8, short is 16, long is 32, and int I think is also
> > 32. I'm pretty sure. That's the values I use when I have to convert
> > those stupid size names in C structures into something that actually
> > exists, and it seems to always work.
> >
> > > i am mixing several integer types to pass to a hardware data structure,
> > > this is not enough, i need exact values.
> >
> > Oh, well, then, if you're doing something hardware specific, I suppose you
> > can say to heck with the portability aspect. So just use char for 8,
> > short for 16, and int for 32 and be done with it.
>
> Thanks for the funny approach... Now i'm convinced that the above values
> for integers must work... Just to let you know i can't say to heck the
> portability aspect because i am porting the module, so the hell is where
> I am :)
>
> Contented, Riba.
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-assembly" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Fred Marmond
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2004-12-30 9:10 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-28 12:29 newbie question about integers size/portabilty Ribamar Santarosa de Sousa
2004-12-28 13:35 ` Richard Cooper
2004-12-28 15:20 ` Ribamar Santarosa de Sousa
2004-12-30 9:10 ` Frederic Marmond
2004-12-28 22:38 ` Brian Raiter
2004-12-28 23:52 ` Ribamar Santarosa de Sousa
2004-12-29 0:17 ` Brian Raiter
2004-12-29 1:05 ` Ribamar Santarosa de Sousa
2004-12-29 1:31 ` Herbert Poetzl
2004-12-29 7:21 ` OT: " Richard Cooper
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 NNTP newsgroup(s).