C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

size of class

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Keshav
Guest





PostPosted: Wed Nov 09, 2005 2:22 pm    Post subject: size of class Reply with quote



Hi,
code snnipet is

class A {
char a;
};
class B {
char b;
int a;
};
class C {
char c;
int d;
char e;
};
int main()
{
cout << sizeof(A) < return 0;
}

Output is 1 8 12
My question is why size of class A is 1. And if it is 1 then why size
of class C is 12. Compiler does padding but why there is different
behaviour for class A and C. either it should be 4 8 12 or 1 8 9?
M i wrong somewhere or it is compiler dependent? I m using Visual C++
..net

Thanks
keshav


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Krakers
Guest





PostPosted: Thu Nov 10, 2005 1:18 pm    Post subject: Re: size of class Reply with quote



Keshav wrote...
Quote:

class A { char a; };
class B { char b; int a; };
class C { char c; int d; char e; };
int main() { cout << sizeof(A) <
Output is 1 8 12. My question is why

If the hardware architecture requires 32-bit integers to be aligned
at addresses divisible by 4 (which often is the case), then, that is
the only way to guarantee that arrays of these classes can still
be accessed.



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
John Potter
Guest





PostPosted: Thu Nov 10, 2005 1:19 pm    Post subject: Re: size of class Reply with quote



On 9 Nov 2005 09:22:55 -0500, "Keshav" <gupta.keshav (AT) gmail (DOT) com> wrote:

Quote:
class A {
char a;
};
class B {
char b;
int a;
};
class C {
char c;
int d;
char e;
};
int main()
{
cout << sizeof(A) < return 0;
}

Output is 1 8 12

It has to do with alignment. sizeof(X) % align(X.m) == 0 always. The
reason is arrays.

Your implementation has align(int) == sizeof(int) == 4 and align(char)
== 1. Sizeof(char) == 1 by definition. Padding between array elements
is not allowed. To align the int in B, there must be padding between it
and the preceeding char. The same is true for C. To align the second C
in an array, the size must be a multiple of the alignment forcing
padding either between the int and the following char or after the char
or both.

Alignment requirements are implementation defined.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Greg Herlihy
Guest





PostPosted: Thu Nov 10, 2005 1:22 pm    Post subject: Re: size of class Reply with quote

Keshav wrote:
Quote:
Hi,
code snnipet is

class A {
char a;
};
class B {
char b;
int a;
};
class C {
char c;
int d;
char e;
};
int main()
{
cout << sizeof(A) < return 0;
}

Output is 1 8 12
My question is why size of class A is 1. And if it is 1 then why size
of class C is 12. Compiler does padding but why there is different
behaviour for class A and C. either it should be 4 8 12 or 1 8 9?
M i wrong somewhere or it is compiler dependent? I m using Visual C++
.net

The sizes of A, B and C would be the same when compiled with any other
C++ compiler whose ints had the same size and alignment requirements.
The size of a POD struct (or POD class) depends only on the size and
the alignment requirements of its member types. To illustrate this
point, let's take the case of a compiler whose ints are both four bytes
in size and four-byte aligned. We can then calculate the sizes of A, B,
and C for such a compiler as follows:

Calculating the size of class A is easy, since it has only one member,
a char. A char is always one byte in size and has no alignment
requirements. Class A therefore will contain no padding. The total size
of an A class object, therefore, is one byte.

Calculating the sizes of classes B and C is a lttle trickier. First, we
know that the compiler will always align a struct or class to meet the
most stringent alignment requirements of any of its members. In the
case of B and C, the only member type with an alignment requirement of
any kind is an int, so objects of class B or C will always be 4-byte
aligned in our implementation.

Now we just add up the members of the class, observing proper alignment
along the way. B and C's first member, c, is a char aligned to a four
byte address. So the member that follows c, d, needs three bytes of
padding so that it can properly aligned to the next four byte address.
Adding up what we have so far:

1 (char) + 3 (padding) + 4 (int) = 8 bytes

The size of a class B object is eight bytes.

Now, adding in C's one additional member, e, a char brings the total to
9 bytes, not the 12 bytes of its actual size. How do we account for
C's additional three bytes?

The answer is that the three extra bytes are needed in order to make C
large enough so that multiple C objects can be stored in an array
contiguously (or more precisely, without any padding between any two
elements). If class C were nine bytes in size, the next C object in an
array could not be both four-byte aligned (to satisfy the aligment
requirements of an int) and also be immediately adjacent to the
preceding C object in memory. So in order to meet both its alignment
requirements and the array storage requirement, class C must be of a
size that will accomodate both. A 12 byte-sized C does so by ensuring
both four-byte alignment and contiguous storage for an array of C
objects.

Lastly, I would also point out that the order that members are declared
within a class can affect its size. For example, rearranging C's
members like so:

class D
{
char c;
char e;
int d;
};

declares a class that stores the same amount of data as C, but in only
two thirds of the space (that is, 8 instead of 12 bytes).

Greg


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze
Guest





PostPosted: Thu Nov 10, 2005 1:27 pm    Post subject: Re: size of class Reply with quote

Keshav wrote:

Quote:
code snnipet is

class A {
char a;
};
class B {
char b;
int a;
};
class C {
char c;
int d;
char e;
};
int main()
{
cout << sizeof(A) < return 0;
}

Output is 1 8 12

My question is why size of class A is 1. And if it is 1 then
why size of class C is 12.

One obvious answer is: why not? The compiler is free to add
padding where ever it wants (except at the beginning of a POD
struct).

In practice, it seems pretty obvious that alignment
considerations are coming into play, and that your compiler
enforces an alignment of 4 for int (and uses 4 byte ints). So
in class B, the offset of a must be 4.

Quote:
Compiler does padding but why there is different behaviour for
class A and C.

Because class A doesn't contain an int, and class C does.
There's no point in maintaining alignment within a structure if
you don't ensure that the size of the structure itself is a
multiple of that alignment. Think of what happens with the
alignment of the second element if you write C[ 2 ].

Quote:
either it should be 4 8 12 or 1 8 9?
M i wrong somewhere or it is compiler
dependent? I m using Visual C++ .net

Well, it's very compiler dependant, but compiler implementors
don't generally just make random decisions -- I'd be very
surprised if any compiler for an Intel platform (or any platform
using 4 byte int's which require an alignment of 4) did
otherwise.

About the only variation I've seen is that a compiler will
insist that all struct's respect a minimum alignment, even when
the contents of the struct doesn't require it. But this is
really only common on word addressed machines, where the
alignment affects pointer size as well. (And as far as I know,
there is only one word addressed machine still being sold
today.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Antoun Kanawati
Guest





PostPosted: Thu Nov 10, 2005 1:32 pm    Post subject: Re: size of class Reply with quote

Keshav wrote:
Quote:
Hi,
code snnipet is

class A { char a; };
class B { char b; int a; };
class C { char c; int d; char e; };
int main() { cout << sizeof(A) <
Output is 1 8 12
My question is why size of class A is 1. And if it is 1 then why size
of class C is 12. Compiler does padding but why there is different
behaviour for class A and C. either it should be 4 8 12 or 1 8 9?
M i wrong somewhere or it is compiler dependent? I m using Visual C++
.net

Padding has to do with alignment. To do the arithmetic, assume
an array of instances; if you align the first instance correctly,
then all the following instances should also be aligned correctly.

So, if you have an int in the middle, it may be necessary to pad
before AND after it, to make the struct line up nicely.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Francis Glassborow
Guest





PostPosted: Thu Nov 10, 2005 1:39 pm    Post subject: Re: size of class Reply with quote

In article <1131521503.655390.120080 (AT) f14g2000cwb (DOT) googlegroups.com>,
Keshav <gupta.keshav (AT) gmail (DOT) com> writes
Quote:
class A {
char a;
};
class B {
char b;
int a;
};
class C {
char c;
int d;
char e;
};
int main()
{
cout << sizeof(A) < return 0;
}

Output is 1 8 12
My question is why size of class A is 1. And if it is 1 then why size
of class C is 12. Compiler does padding but why there is different
behaviour for class A and C. either it should be 4 8 12 or 1 8 9?
M i wrong somewhere or it is compiler dependent? I m using Visual C++
.net
In general the alignment requirements of char types lead to no

requirement for padding. However any user defined type must always have
a size that is at least a multiple of the member with the strongest
alignment requirement.

Hence on systems where int is aligned to a multiple of four bytes, any
type with an int member must have a size that is a multiple of four.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Victor Bogado
Guest





PostPosted: Thu Nov 10, 2005 1:41 pm    Post subject: Re: size of class Reply with quote

This is not really a C++ question, since as far as I know the C++ spec
don't say how the variables should be layouted in memory nor does he
says how much memory should each type is(*).

My guess is that the compiler is aligning the int value. The layout of
the structure in memory is like that :

class a { [a] } = 1
class b { [b] [ ] [ ] [ ] [a] [a] [a] [a] } = 8
class c { [b] [ ] [ ] [ ] [a] [a] [a] [a] [e] } = 9

In my test using the gcc in linux Ubuntu I got the same result, but
this is not necessary, for instance if I had the amd 64 processor the
resul would be certainly different. This is why is not a good idea to
write your objects to the disk as memory dump.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Martin Bonner
Guest





PostPosted: Thu Nov 10, 2005 5:01 pm    Post subject: Re: size of class Reply with quote

John Potter wrote:
Quote:
On 9 Nov 2005 09:22:55 -0500, "Keshav" <gupta.keshav (AT) gmail (DOT) com> wrote:

class A { char a; };
class B { char b; int a; };
class C { char c; int d; char e; }
int main()
{
cout << sizeof(A) < return 0;
}

Output is 1 8 12

It has to do with alignment. sizeof(X) % align(X.m) == 0 always. The
reason is arrays.

Your implementation has align(int) == sizeof(int) == 4 and align(char)
== 1. Sizeof(char) == 1 by definition. Padding between array elements
is not allowed. To align the int in B, there must be padding between it
and the preceeding char. The same is true for C. To align the second C
in an array, the size must be a multiple of the alignment forcing
padding either between the int and the following char or after the char
or both.

Alignment requirements are implementation defined.

This raises a question that has been discussed in the boost list.
Boost has some utility templates that calculate (a multiple of) the
alignment of a type, and a type corresponding to a particular
alignment. On some platforms this latter template is unable to find a
type which corresponds to the result of the former template. The
situation could be improved if it could assume that the alignment
requirement is a power of two.

Clearly the standard does not guarantee that the alignment requirement
is a power of two. However, in practise it usually is.

My question is then: does anyone know of any architecture (in use,
proposed, or defunct) where the natural alignment requirement for a
type was not a power of two?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
James Kanze
Guest





PostPosted: Sun Nov 13, 2005 3:42 pm    Post subject: Re: size of class Reply with quote

Martin Bonner wrote:

[...]
Quote:
Clearly the standard does not guarantee that the alignment
requirement is a power of two. However, in practise it
usually is.

My question is then: does anyone know of any architecture (in
use, proposed, or defunct) where the natural alignment
requirement for a type was not a power of two?

Unisys (ex-Burroughs) Series A. It's not been made for a couple
of years now, but it had 48 bit word size, and I would expect 8
bit bytes. Which would mean an alignment of 6.

On the other hand, I think it was a word addressed machine.
Does the Boost stuff work for word addressed machines. (If not,
there's been a lot of them, and at least one is still being made.)

--
James Kanze mailto: [email]james.kanze (AT) free (DOT) fr[/email]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Martin Bonner
Guest





PostPosted: Mon Nov 14, 2005 3:35 pm    Post subject: Re: size of class Reply with quote


James Kanze wrote:
Quote:
Martin Bonner wrote:

[...]
Clearly the standard does not guarantee that the alignment
requirement is a power of two. However, in practise it
usually is.

My question is then: does anyone know of any architecture (in
use, proposed, or defunct) where the natural alignment
requirement for a type was not a power of two?

Unisys (ex-Burroughs) Series A. It's not been made for a couple
of years now, but it had 48 bit word size, and I would expect 8
bit bytes. Which would mean an alignment of 6.

BOTHER!

Quote:
On the other hand, I think it was a word addressed machine.
Does the Boost stuff work for word addressed machines. (If not,
there's been a lot of them, and at least one is still being made.)

I think it does. It uses (roughly):

alignment = sizeof( struct { char; T } ) - sizeof(T)

I would expect that to produce 6 for anything other than T=char on the
Series A.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze
Guest





PostPosted: Tue Nov 15, 2005 2:32 pm    Post subject: Re: size of class Reply with quote

Martin Bonner wrote:
Quote:
James Kanze wrote:
Martin Bonner wrote:

[...]
Clearly the standard does not guarantee that the alignment
requirement is a power of two. However, in practise it
usually is.

My question is then: does anyone know of any architecture
(in use, proposed, or defunct) where the natural alignment
requirement for a type was not a power of two?

Unisys (ex-Burroughs) Series A. It's not been made for a
couple of years now, but it had 48 bit word size, and I
would expect 8 bit bytes. Which would mean an alignment of
6.

BOTHER!

Before getting too upset about it, I'd find out if it was
relevant to whatever you're doing. I don't know if there was
ever a C++ compiler for it. A priori, the only reason anyone
would be writing code for this machine today is when maintaining
existing code, and if there was never a C++ compiler, then there
probably isn't any existing code to be maintained in C++ either.

Note that this is the only one I know of which was manufactured
recently (i.e. within the last ten years), that if you go back
further in time, you'll find others. CDC's Cyber line (mid
1970's?) used 60 bit words with 12 bit bytes, for example. The
standard convention on a PDP-10 was 7 bit bytes in a 36 bit
word, with one bit not used, but of course, a conforming C/C++
implementation would have to break with that -- sizeof(int) ==
5.14286 just doesn't cut it. (On a PDP-10, byte size was a
field in the instruction, and could in theory be anything from 1
to 36. The obvious solution for C/C++ would be to use 9.)

Note that as far as I know, all of these machines are word
addressed, not byte addressed. I think the IBM 360 (mid
1960's?) was the first machine to use byte addressing, ignoring
the low order bits when accessing larger types (which works best
if the larger types have a size which is a power of 2); before
that, Some convenient word size was chosen (and there was no
real reason for it to be a power of two bits), and then several
characters were stuffed into it, and special instructions
created to access them, with the character selector either in
the high, unused bits of the address or on another word. (On
the other hand, there were also 8 bit machines which worked on
arbitrarily long sequences of bytes, like the 1401. Of course,
the 1401 used decimal arithmetic anyway, and not binary, which
would have caused problems for a C/C++ implementation as well.)

I think that the Unisys was the only one sold after about 1980,
however. And there wasn't much C++ being written back then to
worry about.

Quote:
On the other hand, I think it was a word addressed machine.
Does the Boost stuff work for word addressed machines. (If
not, there's been a lot of them, and at least one is still
being made.)

I think it does. It uses (roughly):

alignment = sizeof( struct { char; T } ) - sizeof(T)

I would expect that to produce 6 for anything other than
T=char on the Series A.

I expect so. Since you asked about power of two, I was
expecting some sort of bit twiddling, perhaps supposing the byte
address on the low order bits of the pointer.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Martin Bonner
Guest





PostPosted: Wed Nov 16, 2005 12:50 pm    Post subject: Re: size of class Reply with quote


kanze wrote:
Quote:
Martin Bonner wrote:
James Kanze wrote:
Martin Bonner wrote:

[...]
Clearly the standard does not guarantee that the alignment
requirement is a power of two. However, in practise it
usually is.

My question is then: does anyone know of any architecture
(in use, proposed, or defunct) where the natural alignment
requirement for a type was not a power of two?

Unisys (ex-Burroughs) Series A. It's not been made for a
couple of years now, but it had 48 bit word size, and I
would expect 8 bit bytes. Which would mean an alignment of
6.

BOTHER!

Before getting too upset about it, I'd find out if it was
relevant to whatever you're doing.

I'm not doing anything. I'm shouting from the sidelines. Other
people are trying to write portable code. "Portable" can have a range
of meanings, a sample (from most to least portable):
- "guaranteed by the standard and implemented by every known
implementation".
- "guaranteed by the standard".
- "not guaranteed by the standard, but implemented that way on every
conceivable machine".
- "all desktops"
- "All Neato compilers"
- "Neato 3.1 with the fimble patch and the /gurble command line option
supplied"

Assuming that alignment was a power of two would step (a little) below
"implemented that way on every conceivable machine".

Quote:
I don't know if there was
ever a C++ compiler for it. A priori, the only reason anyone
would be writing code for this machine today is when maintaining
existing code, and if there was never a C++ compiler, then there
probably isn't any existing code to be maintained in C++ either.

Well quite, but it does weaken the argument "this code will never break
in practise" if somebody can say "what happens if someone comes out
with a Unisys style architecture?"


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.