:
This message was edited by Gregry2 at 2007-3-3 21:21:34
: :
This message was edited by MT2002 at 2007-3-3 14:38:58
: :
: : : : : : This is for the C type.
: : : : : :
: : : : : : Is it assured that short will always be larger in byte size than char on any platform?
: : : : : :
: : : : : : {2}rIng
: : : : : :
: : : : :
: : : : : No
: : : : :
: : : : : But you can asume that...
: : : : : Which brings me to another Q...
: : : : :
: : : : : Why wont this work?
: : : : :
: : : : : int main(){
: : : : : #if sizeof(int)!=4
: : : : : wrong(platform).this(wont, run);
: : : : : #endif
: : : : : }
: : : : :
: : : : :
: : : : : sizeof(int) is constant, and then the preproccessor should be able to find out about it, and then it would work.
: : : : :
: : : : : In a game I'm doing, I need to have a bitfield of size 32 bits, so I used an int32 (very specific to windows compilers) and everything worked fine. Now the problem is that I want to have it portable (since it written with opengl and is thus able to run on all platforms with it implemented(which is a lot)). The only problem is the little int32.
: : : : : It should be possible to replace it with something like this:
: : : : :
: : : : : #if sizeof(short)==4
: : : : : typedef short box;
: : : : : #elif sizeof(int)==4
: : : : : typedef int box;
: : : : : #elif sizeof(long)==4
: : : : : typedef long box;
: : : : : #endif
: : : : :
: : : : :
: : : : : If all the obove would work, then gregry, you could do something like this:
: : : : :
: : : : : #if !(sizeof(short) > sizeof(char))
: : : : : you need a platform where short is bigger than char
: : : : : #endif
: : : : :
: : : : :
: : : :
: : : : 1 method I use (and seen implimented alot of times) is redefining
: : : : the size of data types based on the system in one location. that way,
: : : : for example, an int32 is guranteed to be a 32 bit integer
: : : : on *all* platforms. Same for int64, float32, etc etc.
: : : :
: : : : This is the method Im using for my engine.
: : : :
: : : :
: : :
: : : Hmm, like typedef int int32; ?
: : : But how do you check if it's right?
: : :
: : : I got this kind of code:
: : :
: : : typedef int int32;
: : : int32 a;
: : : ...
: : : a|=0xff000000;
: : :
: : :
: : : Here it would do a very wrong thing if int32 wasn't 32bit...
: : :
: :
: : Kind of. In your example, if a is a 16 bit integer, the bitwise OR would probably just set it to 0 (because the low order bits)
: :
: : This is what I do:
: : #if defined ( _WIN32 )
: : # if defined ( _MSC_VER )
: :
: : // MSVC++ specific..
: : typedef int int32_t; //32bit integer
: : typedef short int16_t; //16bit integer
: :
: : // other data types..
: :
: : # endif
: : #else
: :
: : #if defined ( _WIN16 )
: :
: : typedef int int16_t; //16bit integer (standard int on 16bit
: : // versions of Windows
: :
: : // Because 16bit versions does not support 32bit ints, we need to
: : // emulate them.. (Insure you pack the following struct on 1 byte
: : // bounderies!!)
: :
: : struct int32_t {
: : private:
: : int low, high; // 2 16bit ints= 1 32bit dword
: : public:
: : int32_t () {} // low and high are not initiliazed
: :
: : inline int32_t& operator = (const int32_t& int32) {
: : low=int32.low;
: : high=int32.high;
: : }
: : };
: :
: : #endif
: : #endif
: :
: :
: : Heres a little program (written in MSVC++ 2005) that tests this
: : design:
: : #include <iostream>
: : using namespace std;
: :
: : // pack struct to 1 byte bounderies
: : #pragma pack (push, 1)
: :
: : struct int32_t {
: : private:
: : short low, high; // 2 16bit ints= 1 32bit dword
: : public:
: : int32_t () {} // low and high are not initiliazed
: :
: : // 32bit to 32bit
: : inline int32_t& operator = (const int32_t& int32) {
: : low=int32.low;
: : high=int32.high;
: : }
: :
: : // storing 16bit int in low order byte
: : inline int operator = (const short int16) {
: : int old=low;
: : low=int16;
: : return old;
: : }
: :
: : // 16bit ints only can access low order word
: : inline operator short () {return low;}
: :
: : // etc..
: : };
: :
: : // typedef int32_t to other types..dword, perhaps?
: :
: : // restore standard alignment (useally 32bit)
: : #pragma pack (pop, 1)
: :
: : int main () {
: :
: : int32_t a; // our 32bit data type
: : a= 15; //..
: :
: : // print size (4) and value (15)
: : cout << sizeof (int32_t) << " bytes" << " value: " << a << endl;
: :
: : return 0;
: : }
: :
: : This is one way I seen it implimented. You can hide the struct if its
: : a 32bit platform (and just typedef int int32_t, and use the
: : structure for other platforms.
: :
: : Unfortanly, you will need to create another struct (uint32_t
: : to suport unsigned types.
: :
: : These examples use short data type, which itself is system
: : dependent. If you want portability, insure int32_t uses a
: : int16_t, using a byte_t, int8_t, whatever.
: : The basic idea is that you should insure *every* data type is delared.
: :
: : This might give you some ideas though..
: :
: : *edit:
: : Actually, in MSVC++ 2005, you dont need to pack the struct like I do.
: : (It works either way)
: :
: :
:
: *Every*? Is it really necessary? How about only types whose byte length must be something certain(like variables that are bitfields),
Thats the basic idea. In this case, int32_t is guaranteed
to be a 32bit integer on both Win32 and Win16 platforms.
but not necessarily things it which it isn't important(like iterators whose value probably won't go very high) or char, which is always supposed to be a byte...
If it doesnt matter, then pick one. I would recomment either using
int16_t or int32_t though.
Also, In UNICODE chars are 2 bytes. Multibyte character sets (Such as
unicode) exist for languages with more then 256 characters.
ASCII characters, on the other hand, only set the standard for 256
characters. ASCII characters are guaranteed to be a byte in size.
If you are not working with wide chars or multi byte character sets,
you can simply just assume an unsigned char is a byte, as
you said.
:
: {2}rIng
:
:
: