 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Huang.Antony@gmail.com Guest
|
Posted: Fri Dec 23, 2005 12:55 pm Post subject: unexpect result of sizeof(struct ...) |
|
|
{Despite the compiler specific nature of this code I think the problem
is actually related to Standard C++ which is why I have allowed this
post. -mod/fwg}
Hello,
I have some of codes confused me for a whole day. Follow is my codes'
snap,
class CBase{
public:
CBase(void)
{
int i;
i=0;
}
};
struct foo: public CBase
{
char i[3];
void func(void){};
}__attribute__ ((aligned(4)));
struct bar: public CBase
{
foo a;
foo b;
}__attribute__ ((aligned(4)));
#include <stdio.h>
main(void)
{
printf("foo: %d; bar:%dn", sizeof(foo), sizeof(bar));
}
I compile this code successfully using follow command with gcc3.3 under
Mac OSX10.4,
'gcc -o t.o t.cpp'
Then I run the 't.o', output is,
'foo: 4; bar: 12'
I was confused by the result definitely. I thought the result of
'sizeof(bar)' should score 8 , but the executable file generated by GCC
scores 12 .How to make the result of 'sizeof(bar)' to 8?
Any help much appreciated.
Tony
[ 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
|
Posted: Sat Dec 24, 2005 8:36 am Post subject: Re: unexpect result of sizeof(struct ...) |
|
|
On 23 Dec 2005 07:55:44 -0500, [email]Huang.Antony (AT) gmail (DOT) com[/email] wrote:
| Quote: | I have some of codes confused me for a whole day. Follow is my codes'
snap,
class CBase{
public:
CBase(void)
{
int i;
i=0;
}
};
struct foo: public CBase
{
char i[3];
void func(void){};
}__attribute__ ((aligned(4)));
struct bar: public CBase
{
foo a;
foo b;
}__attribute__ ((aligned(4)));
#include <stdio.h
|
#include
| Quote: | main(void)
{
printf("foo: %d; bar:%dn", sizeof(foo), sizeof(bar));
|
bar b;
assert(static_cast<CBase*>(&b) != static_cast<CBase*>(&b.a));
printf("%p %p %p %pn", &b, static_cast<CBase*>(&b),
&b.a, static_cast<CBase*>(&b.a));
| Quote: | }
I compile this code successfully using follow command with gcc3.3 under
Mac OSX10.4,
'gcc -o t.o t.cpp'
Then I run the 't.o', output is,
'foo: 4; bar: 12'
I was confused by the result definitely. I thought the result of
'sizeof(bar)' should score 8 , but the executable file generated by GCC
scores 12 .How to make the result of 'sizeof(bar)' to 8?
|
The assertion above gives the reason. Two objects of the same type must
not live at the same address. The empty base class of foo can live at
the same address as the member i. The empty base class of bar can not
live at the same address as the member a because there is already an
object of the base class there.
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jack Klein Guest
|
Posted: Sat Dec 24, 2005 8:47 am Post subject: Re: unexpect result of sizeof(struct ...) |
|
|
On 23 Dec 2005 07:55:44 -0500, [email]Huang.Antony (AT) gmail (DOT) com[/email] wrote in
comp.lang.c++.moderated:
| Quote: | {Despite the compiler specific nature of this code I think the problem
is actually related to Standard C++ which is why I have allowed this
post. -mod/fwg}
Hello,
I have some of codes confused me for a whole day. Follow is my codes'
snap,
class CBase{
public:
CBase(void)
{
int i;
i=0;
}
};
struct foo: public CBase
{
char i[3];
void func(void){};
}__attribute__ ((aligned(4)));
|
The "__attribute__ ((aligned(4)))" is some compiler-specific extension
that is not part of the C++ language.
| Quote: |
struct bar: public CBase
{
foo a;
foo b;
}__attribute__ ((aligned(4)));
#include
main(void)
|
C++ does not allow implicit int in function declarations. This code
is ill-formed, you must define it as "int main()". You need to study
your compiler's documentation to determine how to invoke it as a
conforming C++ compiler, so it will issue a diagnostic for this error.
| Quote: | {
printf("foo: %d; bar:%dn", sizeof(foo), sizeof(bar));
|
Your call to printf() produces undefined behavior. The "%d"
conversion requires a value of type int or type unsigned int with a
positive value not greater than INT_MAX. The sizeof operator yields a
type size_t, not an int. At the very least you must cast these values
to int.
| Quote: | }
I compile this code successfully using follow command with gcc3.3 under
Mac OSX10.4,
'gcc -o t.o t.cpp'
Then I run the 't.o', output is,
'foo: 4; bar: 12'
I was confused by the result definitely. I thought the result of
'sizeof(bar)' should score 8 , but the executable file generated by GCC
scores 12 .How to make the result of 'sizeof(bar)' to 8?
Any help much appreciated.
|
A compiler is allowed to introduce padding anywhere in a structure
except before the first member. There is no mechanism defined by the
C++ language to control or modify a compiler's use of padding,
although many compilers provide their own extensions to do this.
There are several things you might try. The first is getting rid of
the non-standard "__attribute__" thing, and see if that makes any
difference.
You could also try removing the "public CBase" from the definition of
the structure type, since it will have two from the foo() classes
anyway.
Finally, you could eliminate the struct bar altogether, and use an
array of two foo objects, which must occupy exactly 2 * sizeof(foo)
bytes.
Or you could consult one of the gnu.gcc help groups to see if there is
a compiler-specific option that might do what you want.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
[ 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
|
Posted: Sat Dec 24, 2005 1:37 pm Post subject: Re: unexpect result of sizeof(struct ...) |
|
|
In article <dgopq1d51umqktup1tbd2n68vjv0o7n23h (AT) 4ax (DOT) com>, Jack Klein
<jackklein (AT) spamcop (DOT) net> writes
| Quote: | {
printf("foo: %d; bar:%dn", sizeof(foo), sizeof(bar));
Your call to printf() produces undefined behavior. The "%d"
conversion requires a value of type int or type unsigned int with a
positive value not greater than INT_MAX. The sizeof operator yields a
type size_t, not an int. At the very least you must cast these values
to int.
|
size_t is required to be an unsigned integer type. I think you are
correct that for an implementation where size_t is an unsigned long and
where that type is not layout compatible with unsigned int the code
would have undefined behaviour. However in the case where size_t is a
typedef for unsigned int the above expression seems to be fine.
IOWs it is implementation defined whether that statement contains
undefined behaviour:-)
--
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 |
|
 |
Jack Klein Guest
|
Posted: Sun Dec 25, 2005 10:47 am Post subject: Re: unexpect result of sizeof(struct ...) |
|
|
On 24 Dec 2005 08:37:41 -0500, Francis Glassborow
<francis (AT) robinton (DOT) demon.co.uk> wrote in comp.lang.c++.moderated:
| Quote: | In article <dgopq1d51umqktup1tbd2n68vjv0o7n23h (AT) 4ax (DOT) com>, Jack Klein
[email]jackklein (AT) spamcop (DOT) net[/email]> writes
{
printf("foo: %d; bar:%dn", sizeof(foo), sizeof(bar));
Your call to printf() produces undefined behavior. The "%d"
conversion requires a value of type int or type unsigned int with a
positive value not greater than INT_MAX. The sizeof operator yields a
type size_t, not an int. At the very least you must cast these values
to int.
size_t is required to be an unsigned integer type. I think you are
correct that for an implementation where size_t is an unsigned long and
where that type is not layout compatible with unsigned int the code
would have undefined behaviour. However in the case where size_t is a
typedef for unsigned int the above expression seems to be fine.
IOWs it is implementation defined whether that statement contains
undefined behaviour:-)
|
That's actually true of quite a few situations in C, and many more of
them in C++. Even the infamous 'i = ++i' is well-defined in C++ if
'i' is a user type with an overloaded operator++.
Note that I mentioned that "%f" requires "...or type unsigned int with
a positive value not greater than INT_MAX." One can deduce from the C
standard that in C all signed and unsigned function arguments of each
integer type must be passed in exactly the same way. If such a
function receives a value of either the signed or unsigned type that
is within the common range of values of both, it functions the same.
This is specifically true for both variadic and non-variadic
functions. In C++ it is true for variadic functions.
But as always, neither language guarantees that the Death Station 9000
passes unsigned int and unsigned long the same, even if they share the
same size and representation. Not that I've ever come across such an
implementation, nor would I willing use one.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
apple.davinci Guest
|
Posted: Sun Dec 25, 2005 10:47 am Post subject: Re: unexpect result of sizeof(struct ...) |
|
|
here is my tries
#include <iostream>
using namespace std;
class CBase
{
public:
CBase(void)
{
int i;
i=0;
}
};
struct foo: public CBase
{
char i[3];
void func(void){};
};
struct bar: public CBase
{
foo a;
foo b;
};
int main()
{
cout<<"sizeof(foo):"<
cout<<"sizeof(bar):"<
}
then execute
[apple@t test]$ ./sizeof_struct
sizeof(foo):3
sizeof(bar):7
any explain
[ 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
|
Posted: Mon Dec 26, 2005 11:50 am Post subject: Re: unexpect result of sizeof(struct ...) |
|
|
On 25 Dec 2005 05:47:39 -0500, "apple.davinci" <apple.davinci (AT) gmail (DOT) com>
wrote:
| Quote: | here is my tries
#include <iostream
|
#include
| Quote: | using namespace std;
class CBase
{
public:
CBase(void)
{
int i;
i=0;
}
};
struct foo: public CBase
{
char i[3];
void func(void){};
};
struct bar: public CBase
{
foo a;
foo b;
};
int main()
{
cout<<"sizeof(foo):"<
cout<<"sizeof(bar):"<
|
bar b;
assert(static_cast
cout << &b << " " << static_cast
<< &b.a << " " << static_cast
<< &b.b << " " << static_cast
| Quote: | }
then execute
[apple@t test]$ ./sizeof_struct
sizeof(foo):3
sizeof(bar):7
|
0x22ef00 0x22ef00
0x22ef01 0x22ef01
0x22ef04 0x22ef04
See prior article. Two objects of the same type may not have the same
address, 5.10. The CBase subobject of b.a has the same address as a.
The CBase suboject of b may not have that address requiring some extra
space in b for it to reside.
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Huang.Antony@gmail.com Guest
|
Posted: Wed Dec 28, 2005 12:37 pm Post subject: Re: unexpect result of sizeof(struct ...) |
|
|
Thanks for your help.
I just think this a defect of gcc. I think maybe the semantic clue of
'sizeof()' is misleaded by gcc.
Just add a class same as 'CBase' and change the declaration of 'bar',
struct bar: public CDummyBase
{
foo a;
foo b;
}__attribute__ ((aligned(4)));
I can get the result of sizeof(bar) score 8 by declaring the bar which
derives from another class. It's the right result for the original
codes if the compiler is enough smart.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Matti Rintala Guest
|
Posted: Wed Dec 28, 2005 6:09 pm Post subject: Re: unexpect result of sizeof(struct ...) |
|
|
[email]Huang.Antony (AT) gmail (DOT) com[/email] wrote:
| Quote: | I just think this a defect of gcc. I think maybe the semantic clue of
'sizeof()' is misleaded by gcc.
|
No, the C++ standard requires the compiler to "not optimise" the empty base
classes in your example. As mentioned in another article in this thread, two
pointers of the same type are allowed to compare equal if and only if they
point to the same object or are both null (this is the only way in C++ to
check the "identity" of an object).
Since both foo and bar in your code are derived from CBase, you can use
CBase pointers to point to them. And since a bar object and its foo data
member are not the same object, CBase pointers to them must not compare
equal. And the only easy way to ensure this is to put them in separate
memory addresses by using extra padding.
| Quote: | Just add a class same as 'CBase' and change the declaration of 'bar',
struct bar: public CDummyBase
{
foo a;
foo b;
}__attribute__ ((aligned(4)));
I can get the result of sizeof(bar) score 8 by declaring the bar which
derives from another class.
|
That's right. Now two pointers of the same type cannot point to bar and foo
(since they no longer have a common base class), so the compiler is allowed
to optimise and put the empty CDummyBase subobject or bar and its foo data
member a to the same memory address.
| Quote: | It's the right result for the original codes if the compiler is enough smart.
|
Nope, the C++ standard does not allow the compiler to be smart in that case
(well, theoretically the compiler is allowed to do the optimisation in the
first case also, if it could prove that the program never compares the bar
and foo objects or does anything else which depends on that).
--
------------- Matti Rintala ------------ [email]matti.rintala (AT) tut (DOT) fi[/email] ------------
Painting is the art of inclusion. Photography is an art of exclusion.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
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
|
|