I'm trying to print out sizeof() values for some of my structures. They are coming out incorrect. Here is a small table in which I've done this on different platforms: Linux : sizeof(TChannel) = 1460 Windows: sizeof(TChannel) = 1460 8051 : sizeof(TChannel) = 1361 Are there byte-alignment issues perhaps? I have both Linux and Windows defaulting to a 1-byte boundary for byte alignment in structures. Does the 8051 default to something different? Here's my code for the 8051: Debugf( "sizeof(TChannel) = %u\r\n", sizeof( TChannel ) ); I've tried %u, %d, %lu, %bu, %X but can't get the right value. Here's my Debugf() function in case that might be messing things up: void Debugf(BYTE* format, ...) { #ifdef DEBUG xdata BYTE buf[64]; va_list arglist; va_start (arglist,format); vsprintf(buf,format,arglist); va_end (arglist); SendSerialData( buf, strlen( buf ) ); #endif } I don't think the problem is in my SendSerialData() function as that seems to work well. Any ideas?
As you found, sizeof should be cast but do you not know that the compiler is free to insert pad bytes in structs *after* the first element for alignment purposes? On the 8051, aligment is to 1 byte thus all structs are "packed". On a 16-bit machine typically padded to 2 bytes, with a 32-bit machine padding to 4 usually.
ISO C99 has finally gotten around to supplying some standard types with specific sizes. <inttypes.h> will give you int8_t, uint8_t, and so on. It also provides some "half-open" types, so you can express the notion of "most convenient/fastest unsigned integer type as long as it's at least 16 bits wide" (uint_least16_t/uint_fast16_t), uintmax_t, intptr_t, conversion and limits macros galore, and so on. Not quite as terse as my favorites (U8, etc), and we're all already used to our home-grown solutions, but support should be available on multiple platforms without having to define them yourself. They also add a "bool" type, which of course introduces all sorts of interesting questions for every platform provider as to how it's implemented.
"On a 16-bit machine typically padded to 2 bytes, with a 32-bit machine padding to 4 usually." I'm sure Mark knows this already, but for the general reader: It can get even more complicated than that; eg, a 32-bit machine may be happy with unaligned 8-bit values, 16-bit values aligned on any even boundary, but 32-bit (or larger) values may need the 4-byte alignment. The compiler may allow you to override this and 'pack' your structures, but that may bring a serious performance hit!! As I keep saying, this is where it is essential that you fully read and understand the compiler Manual - particularly the section on internal data representation!