• 05/03/05 11:06 PM
    Sign in to follow this  

    Tips for Cross-Platform I/O in C/C++

    General and Gameplay Programming

    Myopic Rhino

    If you are writing cross-platform C/C++ code that reads or writes data from/to a file or over the network, then you have to be aware of issues related to language, compiler, and platform differences. The major issues are data alignment, padding, sizes of types, byte order, and whether char is signed or unsigned by default.

    Alignment

    Certain data has to be aligned on certain boundaries on certain machines. If the data is not aligned properly, the results can vary from poor performance to a crash. When you read data from an I/O source into memory, make sure it is aligned correctly.

    Padding

    "Padding" is space added between elements in aggregated data, usually to ensure that they are properly aligned. The amount of padding may differ between compilers and platforms. Do not assume that the size of a struct and the location of its members are the same for all compilers and platforms. Do not read or write an entire struct at once because the program that writes the data might pad it differently than the the program that reads it. This applies to fields, too.

    Sizes of Types

    The sizes of variable types can differ depending on the platform and compiler. In C/C++, the size of an intrinsic type is completely up to the compiler (within certain constraints). Do not read or write types whose sizes are not explicitly specified. In other words, do not read or write bools, enums, longs, ints, shorts, floats, or doubles.

    Use these... ...instead of these
    int8, uint8 char, signed char, unsigned char, enum, bool
    int16, uint16 short, signed short, unsigned short, enum
    int32, uint32 int, signed int, unsigned int, long, signed long, unsigned long, enum
    int64, uint64 long, signed long, unsigned long
    int128, uint128 long long, signed long long, unsigned long long
    float32 float
    float64 double

    Byte order

    The byte order of a value is the order that the bytes are stored in memory. Different processors store multi-byte numbers in memory in different orders. Little-endian processors store bytes in the order of least significant byte to most significant byte (in other words, backwards from the way numbers are written). Big-endian processors store bytes in the order of most significant byte to least significant byte (the same way numbers are written). If the byte order of a value does not match the byte order of the processor that is reading or writing it, then it must be converted. Also, as a way to standardize the order of bytes transmitted over a network, there is a network byte order.

    char - signed or unsigned?

    A little-known fact is that char can be signed or unsigned by default -- it is up to the compiler. The result is that when you convert from char to another type (such as int), the result can differ depending on the compiler. For example:

    char   x;
    int    y;
    
    read( fd, &x, 1 );   // read a byte with the value 0xff
    y = x;               // y is 255 or -1, depending on the compiler
    

    Do not read a value into a generic char. Always specify signed or unsigned.



      Report Article
    Sign in to follow this  


    User Feedback

    Create an account or sign in to leave a review

    You need to be a member in order to leave a review

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

    There are no reviews to display.