A simple (?) question about the size of structs

B

Bryan Feeney

This structure is, according to sizeof, 3 bytes long, which makes sense

struct test
{ char text[3];
};

This structure is, according to sizeof, 4 bytes long, which also makes sense

struct test
{ int number;
};

This structure is, according to sizeof, 8 bytes long, which is confusing the
hell out of me!

struct test
{ char text[3];
int number;
};

Where is the extra byte coming from? It's not something I need to know, but
I'd like to know what's going on. I'm using GCC3 on Windows via MinGW as
supplied by the Bloodshed Dev-C++ IDE (verson 4.9.8.0).


Thanks in advance
 
C

Chris McDonald

Bryan Feeney said:
This structure is, according to sizeof, 3 bytes long, which makes sense
struct test
{ char text[3];
};
This structure is, according to sizeof, 4 bytes long, which also makes sense
struct test
{ int number;
};
This structure is, according to sizeof, 8 bytes long, which is confusing the
hell out of me!
struct test
{ char text[3];
int number;
};
Where is the extra byte coming from? It's not something I need to know, but
I'd like to know what's going on. I'm using GCC3 on Windows via MinGW as
supplied by the Bloodshed Dev-C++ IDE (verson 4.9.8.0).


Your compiler and/or host architecture prefer or require to align
the integer field on a 4-byte boundary. At least under Unix on some
architectures, this may be required to avoid bus-errors occuring at
run-time, or preferred (for speed) so that the integers do not need
aligning at run-time.

That said, there can be other "gotchas" with some compilers/architectures:

struct {
char a;
int i;
char b;
}

The sizeof() this may still be 8 bytes, if the compiler chooses to pack
the two characters into the 4-byte space before (or after) the integer.

It is something of which you should be aware, if writing sizeof(structs)
to files or "down" a network connection.

_______________________________________________________________________________
Dr Chris McDonald EMAIL: (e-mail address removed)
School of Computer Science & Software Engineering
The University of Western Australia WWW: http://www.csse.uwa.edu.au/~chris
Crawley, Western Australia, 6009 PH: +61 8 6488 2533, FAX: +61 8 6488 1089
 
K

Kevin Bracey

In message <[email protected]>
Chris McDonald said:
That said, there can be other "gotchas" with some compilers/architectures:

struct {
char a;
int i;
char b;
}

The sizeof() this may still be 8 bytes, if the compiler chooses to pack
the two characters into the 4-byte space before (or after) the integer.

The rule about structures with common initial sequences in unions restricts
that slightly.

The addition of a member to the end of a structure is not allowed to change
the positions of earlier members.

Thus 'b' could be tucked in between 'a' and 'i', but 'a' couldn't be
placed after 'i'.

Is anyone actually aware of any implementations that do this though?
 
D

Dan Pop

In said:
In message <[email protected]>


The rule about structures with common initial sequences in unions restricts
that slightly.

The addition of a member to the end of a structure is not allowed to change
the positions of earlier members.

Thus 'b' could be tucked in between 'a' and 'i', but 'a' couldn't be
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
placed after 'i'.

Nonsense!

13 Within a structure object, the non-bit-field members and the
units in which bit-fields reside have addresses that increase in
the order in which they are declared.

There is no way to have 'b' allocated before 'i'. Note that a correct
C program can trivially check this (e.g. using the offsetof macro) so
the as-if rule doesn't apply.

Dan
 
T

Thomas Matthews

Bryan said:
This structure is, according to sizeof, 3 bytes long, which makes sense

struct test
{ char text[3];
};

This structure is, according to sizeof, 4 bytes long, which also makes sense

struct test
{ int number;
};

This structure is, according to sizeof, 8 bytes long, which is confusing the
hell out of me!

struct test
{ char text[3];
int number;
};

Where is the extra byte coming from? It's not something I need to know, but
I'd like to know what's going on. I'm using GCC3 on Windows via MinGW as
supplied by the Bloodshed Dev-C++ IDE (verson 4.9.8.0).


Thanks in advance

Here is the rule on the sizes of structures:
The size of a structure may not be the sum of the sizes of its fields.

Reasoning:
Compilers are allowed to insert "padding" bytes between fields.
Compilers can also add "bookkeeping" information in the structure
as well.

Some compilers like to keep the fields "aligned" to certain address
boundaries, such as 16-bit and 32-bits. This helps processors
access the data in a more efficient manner.

Mapping Structures To Data Or Hardware
Because of the padding rule, structures cannot be portably used to
map data to external formats (such as message formats or hardware
registers). One may keep the structure, but there must be code
to convert the external layout to the internal one.

Given a message header of:
command [8-bits]
length [16-bits]
The structure of:
struct Message
{
unsigned char command; /* CHAR_BITS == 8 */
unsigned short length;
};
allows the compiler to insert padding between the command and
length fields, so that they won't match the incoming data. And
not forgetting that an "unsigned short" or even "unsigned int"
may be larger than the 16-bits in the message.

However, once the data is placed into the structure variables,
the program can reference the fields with no problem. It's
just that the data has to be reformatted when outputting.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
P

Peter Ammon

Bryan said:
This structure is, according to sizeof, 3 bytes long, which makes sense

struct test
{ char text[3];
};

This structure is, according to sizeof, 4 bytes long, which also makes sense

struct test
{ int number;
};

This structure is, according to sizeof, 8 bytes long, which is confusing the
hell out of me!

struct test
{ char text[3];
int number;
};

Where is the extra byte coming from? It's not something I need to know, but
I'd like to know what's going on. I'm using GCC3 on Windows via MinGW as
supplied by the Bloodshed Dev-C++ IDE (verson 4.9.8.0).


Thanks in advance

I'm really surprised that nobody has pointed out that this is a FAQ.

<http://www.eskimo.com/~scs/C-faq/q2.13.html>

-Peter
 
M

Mark McIntyre

This structure is, according to sizeof, 8 bytes long, which is confusing the
hell out of me!

struct test
{ char text[3];
int number;
};

Where is the extra byte coming from?

FAQ 2.12 and 2.13
 
G

glen herrmannsfeldt

Dan Pop wrote:

(someone wrote)

(someone else wrote)
Nonsense!
13 Within a structure object, the non-bit-field members and the
units in which bit-fields reside have addresses that increase in
the order in which they are declared.
There is no way to have 'b' allocated before 'i'. Note that a correct
C program can trivially check this (e.g. using the offsetof macro) so
the as-if rule doesn't apply.

Can the compiler detect use of the offsetof macro?

There are stories related to SPEC and tricks compilers
use when they discover that they are compiling a SPEC program.

Or maybe only when a certain compiler flag is set to allow it.

-- glen
 
D

Dan Pop

In said:
Dan Pop wrote:

(someone wrote)


(someone else wrote)





Can the compiler detect use of the offsetof macro?

What the compiler cannot detect is the usage of the offsetof macro
in another translation unit using the same structure ;-)
There are stories related to SPEC and tricks compilers
use when they discover that they are compiling a SPEC program.

What is not a story is that many commercial compilers have their
optimisers tuned for the SPEC programs. As a result, the compiler
generates optimal code for the SPEC programs naturally, without making
any attempt to recognise them.

Dan
 

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

No members online now.

Forum statistics

Threads
474,141
Messages
2,570,818
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top