VC6: 1+4=8 WHY???

M

Marcin P

I have a structure:
typedef struct {
signed char var1;
unsigned long int var2;
} MYSTRUCT;

Now look:
sizeof(signed char)=1 (byte)
sizeof(unsigned long int)=4 (bytes)

Tell me why:
sizeof(MYSTRUCT)=8 ??? (bytes)
Why it's not 1+4=5 bytes?

Regards
 
A

Andre Kostur

I have a structure:
typedef struct {
signed char var1;
unsigned long int var2;
} MYSTRUCT;

Now look:
sizeof(signed char)=1 (byte)
sizeof(unsigned long int)=4 (bytes)

Tell me why:
sizeof(MYSTRUCT)=8 ??? (bytes)
Why it's not 1+4=5 bytes?

A couple of concepts to look up: byte packing, or structure alignment.

On whatever platform you're on, the CPU can more easily address items on a
word boundary. So in your struct, it will try to put your members on word
boundaries. So, you'll have 1 byte of var1, 3 bytes of filler, then 4
bytes of var2 for a total size of 8 bytes.
 
C

CrayzeeWulf

S

Stephen Howe

sizeof(MYSTRUCT)=8 ??? (bytes)
Why it's not 1+4=5 bytes?

There are padding bytes after var1 in order to make sure var2 starts on
address that is divisible by 4. On some architectures, accessing val2 on an
address not divisible by 4 would terminate the program.

Most compilers give you a compiler option to pack classes/structs and some
also have a pragma directive which gives you individual
struct/class-by-struct/class

Stephen Howe
 
C

codigo

Marcin P said:
I have a structure:
typedef struct {
signed char var1;
unsigned long int var2;
} MYSTRUCT;

Now look:
sizeof(signed char)=1 (byte)
sizeof(unsigned long int)=4 (bytes)

Tell me why:
sizeof(MYSTRUCT)=8 ??? (bytes)
Why it's not 1+4=5 bytes?

Regards

Consider the effects if your compiler didn't align a MYSTRUCT variable's
composition. Take an array of MYSTRUCT variables and the fact that the
compiler would have to index-shift over each instance in the container to
eliminate the waisted space. Then consider how the same complex index-based
addressing scheme would be required to read, write or deallocate each
instance.

Speed is far more critical than the space occupied by an instance of that
class or a container of these. Not to mention the added complexity of the
programming itself, the compiler, or the hardware re-engineering issues such
a scheme would produce.
 
M

Marcin P

codigo napisa³(a):
Consider the effects if your compiler didn't align a MYSTRUCT variable's
composition. Take an array of MYSTRUCT variables and the fact that the
compiler would have to index-shift over each instance in the container to
eliminate the waisted space. Then consider how the same complex index-based
addressing scheme would be required to read, write or deallocate each
instance.

Speed is far more critical than the space occupied by an instance of that
class or a container of these. Not to mention the added complexity of the
programming itself, the compiler, or the hardware re-engineering issues such
a scheme would produce.
Thank's for all replays! Now I know what's going on.

So if I want to read a bitmap file header (14 bytes) and pack in to
fallowing structure:

typedef struct _BITMAPFILEHEADER { // Offset Size
short bfType; // 0 2
long bfSize; // 2 4
short bfReserved1; // 6 2
short bfReserved2; // 8 2
long bfOffBits; // 10 4
} BITMAPFILEHEADER; // Total size: 14
....
BITMAPFILEHEADER bitmapFileHeader;

I can't just use:

fread(bitmapFileHeader,sizeof(BITMAPFILEHEADER),1,filePointer)

because data will be filled incorrectly.
Better idea will be something like that:

fread(bitmapFileHeader.bfType,sizeof(short),1,filePointer);
fread(bitmapFileHeader.bfSize,sizeof(long),1,filePointer); etc. etc.

or try to align the variables in structure.
 
U

ulrich

I have a structure:
typedef struct {
signed char var1;
unsigned long int var2;
} MYSTRUCT;

Now look:
sizeof(signed char)=1 (byte)
sizeof(unsigned long int)=4 (bytes)

Tell me why:
sizeof(MYSTRUCT)=8 ??? (bytes)
Why it's not 1+4=5 bytes?

the answer is padding - padding memory with zero-bytes.
the reason is that today's desktop CPUs love to eat data in 32-bit bits ;)
 
H

Heinz Ozwirk

Marcin P said:
So if I want to read a bitmap file header (14 bytes) and pack in to
fallowing structure:

typedef struct _BITMAPFILEHEADER { // Offset Size
short bfType; // 0 2
long bfSize; // 2 4
short bfReserved1; // 6 2
short bfReserved2; // 8 2
long bfOffBits; // 10 4
} BITMAPFILEHEADER; // Total size: 14
...
BITMAPFILEHEADER bitmapFileHeader;

I can't just use:

fread(bitmapFileHeader,sizeof(BITMAPFILEHEADER),1,filePointer)

because data will be filled incorrectly.
Better idea will be something like that:

fread(bitmapFileHeader.bfType,sizeof(short),1,filePointer);
fread(bitmapFileHeader.bfSize,sizeof(long),1,filePointer); etc. etc.

Even better:
fread(bitmapFileHeader.bfType,2,1,filePointer);
fread(bitmapFileHeader.bfSize,4,1,filePointer);
etc.

Even though many binary file formats are described in terms of C structs, they always assume very specific alignment and sizes for various types. None of these must be the same for the compiler used to read/write such a file. So don't depend on sizeof(...) when reading or writing from and to such files. The file defines the size of its elements, not the compiler used to compile the code working with the file.

BTW: Where did you get the definition of BITMAPFILEHEADER? The definition provided by MS uses WORD and DWORD instead of short and long, indicating that these values should be 16 or 32 bits, no matter which compiler or language you are using.

Heinz
 
P

Pete Becker

Marcin said:
Thank's for all replays! Now I know what's going on.

So if I want to read a bitmap file header (14 bytes) and pack in to
fallowing structure:

typedef struct _BITMAPFILEHEADER { // Offset Size
short bfType; // 0 2
long bfSize; // 2 4
short bfReserved1; // 6 2
short bfReserved2; // 8 2
long bfOffBits; // 10 4
} BITMAPFILEHEADER; // Total size: 14
...
BITMAPFILEHEADER bitmapFileHeader;

I can't just use:

fread(bitmapFileHeader,sizeof(BITMAPFILEHEADER),1,filePointer)

because data will be filled incorrectly.

Not necessarily. You've gotten a bunch of sweeping generalizations, none
of which is required by the language defintion. The only correct answer
is that if you wrote it with fwrite you can read it with fread, provided
you used the same compiler to generate the code in both cases.
 
A

Andre Kostur

codigo napisa³(a):
Thank's for all replays! Now I know what's going on.

So if I want to read a bitmap file header (14 bytes) and pack in to
fallowing structure:

typedef struct _BITMAPFILEHEADER { // Offset Size
short bfType; // 0 2
long bfSize; // 2 4
short bfReserved1; // 6 2
short bfReserved2; // 8 2
long bfOffBits; // 10 4
} BITMAPFILEHEADER; // Total size: 14
...
BITMAPFILEHEADER bitmapFileHeader;

I can't just use:

fread(bitmapFileHeader,sizeof(BITMAPFILEHEADER),1,filePointer)

because data will be filled incorrectly.
Better idea will be something like that:

fread(bitmapFileHeader.bfType,sizeof(short),1,filePointer);
fread(bitmapFileHeader.bfSize,sizeof(long),1,filePointer); etc. etc.

or try to align the variables in structure.

Not necessarily.... check your compiler documentation on how you may be
able to force the compiler to use 1-byte alignment. Note that the
drawback here is that accessing the unaligned members may be less
efficient than normal to compensate for the unaligned accesses to memory.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,292
Messages
2,571,495
Members
48,185
Latest member
abhaysingh01

Latest Threads

Top