Why 'S32' instead of 'int', etc?
by Steven Peterson · in Torque Game Engine · 02/16/2006 (11:50 am) · 16 replies
Yet another question...
Why do I see "types" like 'S32', 'U32', and 'F32' used instead of 'int', 'float' and 'double' throughout Torque. I've never heard of these before in general, is this simply a torque convention? And what is the advantage to adopting this convention instead of using standard variable types?
I saw this page: http://www.garagegames.com/docs/tge/engine/types_8h.php
but i'm still not entirely sure what to use when, or why...
Thanks,
Raven
Why do I see "types" like 'S32', 'U32', and 'F32' used instead of 'int', 'float' and 'double' throughout Torque. I've never heard of these before in general, is this simply a torque convention? And what is the advantage to adopting this convention instead of using standard variable types?
I saw this page: http://www.garagegames.com/docs/tge/engine/types_8h.php
but i'm still not entirely sure what to use when, or why...
Thanks,
Raven
#2
I am also farily certain that they are used for cross platform compatability
02/16/2006 (12:19 pm)
With my marginal programming experience i would say that, S32 are used if you need to be able to store negative or positive values and U32 are for only positive ... Signed and unsigned. Obviously U32 would be smaller... faster, if I am correct.I am also farily certain that they are used for cross platform compatability
#3
i'm curious too, tho, what U32 and S32 get you which the standards don't:
types.h:
edit:
i thought the reasoning would be to get consistent bit-length for these basic types,
but i don't see how those typedefs would effect that.
.. unless "signed" and "unsigned" force 32 bits.
02/16/2006 (12:29 pm)
Standard C/C++ has types for signed and unsigned as well-int signedInteger; unsigned int unsignedInteger;
i'm curious too, tho, what U32 and S32 get you which the standards don't:
types.h:
typedef signed int S32; ///< Compiler independent Signed 32-bit integer typedef unsigned int U32; ///< Compiler independent Unsigned 32-bit integer
edit:
i thought the reasoning would be to get consistent bit-length for these basic types,
but i don't see how those typedefs would effect that.
.. unless "signed" and "unsigned" force 32 bits.
#4
By labeling a type a U32, you can be assured that no matter what platform you are on, the U32 is really an unsigned 32-bit (4 byte) value and not something else. This can be accomplished by checking the size limits in a platform's and then typedef'ing to the appropriate types.
02/16/2006 (12:42 pm)
Neil is right. This is done because of cross-platform considerations. A double or an int may have a certain size on one platform, but be completely different on another! For instance, on one particular DSP that I've worked with (TI TMS320C6414 DSP for the curious), a long was 40-bits wide. By labeling a type a U32, you can be assured that no matter what platform you are on, the U32 is really an unsigned 32-bit (4 byte) value and not something else. This can be accomplished by checking the size limits in a platform's
#5
It seems the purpose is to force fixed/constant variable lengths and functionality cross-platform even though I also do not see how this is accomplished. Does anyone know for sure? (wonders if this is how urban-legends get started...)
I've also determined the following - maybe this will help others - PLEASE correct me if i'm wrong:
U8 = unsinged 'small int'
U16 = unsigned 'int'
U32 = unsigned 'long int' or 'double'
U64 = unsigned 'long long int'
S8 = singed 'small int'
S16 = signed 'int'
S32 = signed 'long int' or 'double'
S64 = signed 'long long int'
F8 = float (8-bit)
F16 = float ( 16-bit)
F32 = float ( 32-bit)
F64 = float ( 64-bit)
other?
[edit]
Thanks Andrew for clairifying! I think our posts crossed in the mail so-to-speak. :-P
[/edit]
02/16/2006 (12:53 pm)
I'm learning as I go (as always :-) but I'm in the same boat as you guys: It seems the purpose is to force fixed/constant variable lengths and functionality cross-platform even though I also do not see how this is accomplished. Does anyone know for sure? (wonders if this is how urban-legends get started...)
I've also determined the following - maybe this will help others - PLEASE correct me if i'm wrong:
U8 = unsinged 'small int'
U16 = unsigned 'int'
U32 = unsigned 'long int' or 'double'
U64 = unsigned 'long long int'
S8 = singed 'small int'
S16 = signed 'int'
S32 = signed 'long int' or 'double'
S64 = signed 'long long int'
F8 = float (8-bit)
F16 = float ( 16-bit)
F32 = float ( 32-bit)
F64 = float ( 64-bit)
other?
[edit]
Thanks Andrew for clairifying! I think our posts crossed in the mail so-to-speak. :-P
[/edit]
#6
02/16/2006 (12:59 pm)
Here is an example on how to guarantee your type lengths:#include <limits.h> ... #if UINT_MAX == 4294967295U typedef unsigned int u32; //!< Unsigned int, 4 byte #elif UINT_MAX = 65535U typedef unsigned int u16; //!< Unsigned int, 2 byte #error Unexpected UINT_MAX. #endif ...
#7
can you explain how this is acheived via the typedefs in platform/types.h ? are U32 and S32 special symbols ?
02/16/2006 (1:01 pm)
@Andrew -Quote:
By labeling a type a U32, you can be assured that no matter what platform you are on, the U32 is really an unsigned 32-bit (4 byte) value and not something else.
can you explain how this is acheived via the typedefs in platform/types.h ? are U32 and S32 special symbols ?
#8
02/16/2006 (1:03 pm)
Orion: See post above. :)
#9
.. oh i guess they have a different types.h for each platform.
i don't think they're checking UINT_MAX tho.
edit: heh. this thread is too hot to handle !
02/16/2006 (1:03 pm)
.. this second post of yours makes sense to me, yes... oh i guess they have a different types.h for each platform.
i don't think they're checking UINT_MAX tho.
edit: heh. this thread is too hot to handle !
#10
GG might not be checking UINT_MAX - I do not have the TGE code in front of me at the moment. If not, they should. :)
02/16/2006 (1:13 pm)
@ Orion. That's right. Each silicon and/or compiler vendor should ship a limits.h file with their C/C++ SDK/compiler. GG might not be checking UINT_MAX - I do not have the TGE code in front of me at the moment. If not, they should. :)
#11
I guess so - every once in a while I write a winner.. ;-)
And, to my further understanding, this has already been done for us in Torque, so all I have to do is use the new types (S16, U16 and F16, etc). However, it seems a good trick to remember for future projects. That pretty much sum it up?
Thanks all!
Raven
02/16/2006 (1:14 pm)
Quote:
edit: heh. this thread is too hot to handle !
I guess so - every once in a while I write a winner.. ;-)
Quote:
This can be accomplished by checking the size limits in a platform'sand then typedef'ing to the appropriate types.
And, to my further understanding, this has already been done for us in Torque, so all I have to do is use the new types (S16, U16 and F16, etc). However, it seems a good trick to remember for future projects. That pretty much sum it up?
Thanks all!
Raven
#12
one example why you need those for cross compiler and cross platform compability is that if you write an int to a file. For 64 bit compilers an int is 64 bits while on normal 32 bit platforms its 32 bits AFAIK. So if you write an int to a file with a 32 bit version of your game it would write 4 bytes. Now if you read this file with your 64 bit version of your game it now would read 8 bytes from that file to fill one int structure. So either you will try to read over the files bounds (if this file is only that one int) or you will read completely false data since you also read the next int. Torque uses streams to pack data to be sent over the net. if the other client doesnt know exactly how big a specific piece of data is he couldnt unpack the data correctly again.
02/16/2006 (4:01 pm)
Typedefs are a C++ construct ... they allow to create new types from existing ones. So in some sort they create an Alias for a built in type.typedef unsigned int U32 // U32 is now known and it is an unsigned int typedef unsigned int* pU32 // pU32 is now known and it is a pointer to an unsigned int typedef unsigned int BigU32Array[2000] // BigU32 is now known and it is a Array of U32 with 2000 items // you can now do this here U32 MyInt; pU32 MyIntPointer; BigU32Array MyArray;
one example why you need those for cross compiler and cross platform compability is that if you write an int to a file. For 64 bit compilers an int is 64 bits while on normal 32 bit platforms its 32 bits AFAIK. So if you write an int to a file with a 32 bit version of your game it would write 4 bytes. Now if you read this file with your 64 bit version of your game it now would read 8 bytes from that file to fill one int structure. So either you will try to read over the files bounds (if this file is only that one int) or you will read completely false data since you also read the next int. Torque uses streams to pack data to be sent over the net. if the other client doesnt know exactly how big a specific piece of data is he couldnt unpack the data correctly again.
#13
right, but what i don't see is why the following line guarantees that U32 will be 4 bytes and not 8:
I think you need some other piece to the puzzle to check what size unsigned int is,
which is i think what Andrew was saying.
02/16/2006 (4:14 pm)
@ Florian -right, but what i don't see is why the following line guarantees that U32 will be 4 bytes and not 8:
typedef unsigned int U32;
I think you need some other piece to the puzzle to check what size unsigned int is,
which is i think what Andrew was saying.
#14
some example (not sure if microsofts 64 compiler really does make int 64 bits but i'll just assume it here)
this way you can safely use U32 and be sure that it is 32 bits because you (as the programmer) explicitly set it so :)
02/17/2006 (4:46 am)
It doesnt do that alone but the programmer can controll it:some example (not sure if microsofts 64 compiler really does make int 64 bits but i'll just assume it here)
#ifdef WIN64 typedef unsigned short U32; // is 4 bytes on 64 bit platforms #else typedef unsigned int U32; // is 4 bytes on 32 bit platforms #endif
this way you can safely use U32 and be sure that it is 32 bits because you (as the programmer) explicitly set it so :)
#15
02/17/2006 (10:34 am)
Roger, thanks.
#16
02/17/2006 (4:40 pm)
One thing to keep in mind is that even if there aren't any differences in how the numbers are stored among the currently supported platforms, Torque was written to be very portable among *any* platform. By using the built-in types (U32, S32, F32, U16, etc.) in the rest of the engine code you minimize the porting work for a new platform to just creating a new types.h instead of having to go change hundreds of thousands of references to "int".
Torque Owner Neil Marshall