-
September 20th, 2010, 03:48 AM
#1
How do I specify types with exact byte lengths?
I need a two byte integer and a four byte integer. I could use a short and an int, but how I would specify such integers so as to guarantee their length?
-
September 20th, 2010, 04:19 AM
#2
Re: How do I specify types with exact byte lengths?
Originally Posted by codingnewbie
I need a two byte integer and a four byte integer. I could use a short and an int, but how I would specify such integers so as to guarantee their length?
First of all, a short and an int are NOT four bytes. Your only guarantee is that the size of short is smaller or equal to the size of int, and that both short and int hold at least 0 to 653535 (-32767 to 32767 if signed). That's it. In this case, it is a short and a long. But they may be longer.
Ideally, there are two solutions:
Your project has a defines.h file, that defines the macro UInt32 and UInt16 (for example), that guarantees these objects are of the type you want (by using various macros that look at the current compiler/system).
In this case, all you need to do is:
struct myShortAndIntStruct
{
UInt_16 myShort;
UInt_32 myInt;
}
I highly recommend this solution
The second solution: If you absolutely need you variables to be an exact binary length, then use a bit struct aka bit filed:
Code:
struct myShortAndIntStruct
{
short int myShort : 16;
int : 0; //Anonymous member of size 0: Forces alignment of next member
long int myInt : 32;
};
While this solution is what you are asking for, it may not be what you want.
Unless you are writing a driver, or are writing to a binary file, you shouldn't need variables that "are two bytes" but variables "that can hold at least two bytes". In this case, a simple short and long are what you are looking for.
A simple structure as recommended in solution 1 would be much better: A bitfield imposes varaible unpacking overhead, and since the objects are packed, it is impossible to access the variables by reference.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
September 20th, 2010, 04:47 AM
#3
Re: How do I specify types with exact byte lengths?
Originally Posted by codingnewbie
I need a two byte integer and a four byte integer. I could use a short and an int, but how I would specify such integers so as to guarantee their length?
To add, if you must guarantee that the types are of a certain length before a compilation can be successful , a quick and dirty code snippet:
Code:
struct SizeCheck__
{
char tmp__[sizeof(mytype_short)==2?1:0];
char tmp2__[sizeof(mytype_int)==4?1:0];
};
If this struct is being compiled, the code will not compile successfully if the types you chose (mytype_short and mytpe_int) are not what you expect them to be.
Regards,
Paul McKenzie
-
September 20th, 2010, 11:59 AM
#4
Re: How do I specify types with exact byte lengths?
While Paul's suggestion will work, it would be more obvious what's going on to do a
Code:
static_assert(sizeof(int) == 4 && sizeof(short) == 2, "Types do not have expected sizes");
where static_assert is std::static_assert under the newest gcc or VS2010, or else boost::static_assert on older compilers.
I would also mention that while it is not a C++ header, there is a C99 header called stdint.h which contains sized integer types.
-
September 20th, 2010, 03:36 PM
#5
Re: How do I specify types with exact byte lengths?
MSVC does not have a stdint.h but here's one solution http://code.google.com/p/msinttypes/
If you only write code for Windows and use MSVC you can use the following types __int8, __int16, __int32 and __int64.
-
September 20th, 2010, 10:21 PM
#6
Re: How do I specify types with exact byte lengths?
Code:
struct myShortAndIntStruct
{
short int myShort : 16;
int : 0; //Anonymous member of size 0: Forces alignment of next member
long int myInt : 32;
};
To OP, as carefully commented in the example code, the packing of these bitfields does not guarantee the alignment regardless how we instruct the compiler because it is implementation defined. Using bitfield in this case is not suitable for your need.
-
September 22nd, 2010, 07:54 AM
#7
Re: How do I specify types with exact byte lengths?
Thanks for the info. I was just trying to make a program that produced a wav file with a simple sine wave and needed specific sizes for the header and audio data. It was just a test and it worked fine with just the short and int types on my system, but i was just curious how you would go about specifying exact sizes if you needed them.
-
September 22nd, 2010, 08:34 AM
#8
Re: How do I specify types with exact byte lengths?
Originally Posted by codingnewbie
Thanks for the info. I was just trying to make a program that produced a wav file with a simple sine wave and needed specific sizes for the header and audio data. It was just a test and it worked fine with just the short and int types on my system, but i was just curious how you would go about specifying exact sizes if you needed them.
In c++, you can't demand for anything to by of any given size. At best, you can observe that something is a given size on a platform, and use that.
In your case, I would write a header like this at the top of my program:
Code:
typedef int int32; //int is 32 bits on my platform
typedef short int16; //short is 16 bits on my platform
And then, I would use the int16 and int32 types. This way, if I ever change from a 32 bit windows to a 64 bit linux, those would be the only two lines of code I would change.
At best, I would write a file like this:
Code:
integer_types.h
char char_is_8_bits[CHAR_BITS==8]; //static assert that a byte is 8 bits
#ifdef windows //not actual macro
typedef long int32;
typedef short int16;
#else ifdef linux //not actual macro
typedef int int32;
typedef short int16;
#else
#error Please provide typedefs for this platform
#endif
char int32_is_4_bytes[sizeof(int32)==4]; static assert
char int16_is_2_bytes[sizeof(int16)==2]; static assert
With this, you should be able to guarantee that an object is indeed the desired size, regardless of platform/compiler
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
September 22nd, 2010, 08:36 AM
#9
Re: How do I specify types with exact byte lengths?
What you want to do is serialize your struct: write/read every value one by one, given their object size (using the types as described above). WHATEVER YOU DO, don't binary write an entire struct at once! Given the different alignment of different platforms, it will not work reliably.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|