CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    May 2007
    Posts
    26

    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?

  2. #2
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: How do I specify types with exact byte lengths?

    Quote Originally Posted by codingnewbie View Post
    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.

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: How do I specify types with exact byte lengths?

    Quote Originally Posted by codingnewbie View Post
    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

  4. #4
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    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.

  5. #5
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    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.
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  6. #6
    Join Date
    Jan 2008
    Location
    California, USA
    Posts
    822

    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.

  7. #7
    Join Date
    May 2007
    Posts
    26

    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.

  8. #8
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: How do I specify types with exact byte lengths?

    Quote Originally Posted by codingnewbie View Post
    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.

  9. #9
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    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
  •  





Click Here to Expand Forum to Full Width

Featured