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 

empty base class optimization

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





PostPosted: Fri Jul 30, 2004 9:54 am    Post subject: empty base class optimization Reply with quote



Hello,

While reading another thread about sizeof base-classes, I ran the
following program on GCC 3.2

#include <iostream>
#include <ostream>
struct a{};

struct b : public a{};

int main()
{
std::cout << sizeof(b) << "n";
std::cout << sizeof(b::a);
}

The output is:

1
1

so we se in the first case EBO during work. However, I am not sure the
second output is correct as the standard defines it. Yes, an object must
practically have a size >= 1, but doen't the scope access operator
direclty request a base-class object of b with size 0 ?

Am I experiencing an restriction that is required, or is this a hole in
the standard (the b::a access, where sizeof(a) = 0 in the EBO case)?

thank you,

Thomas

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





PostPosted: Fri Jul 30, 2004 3:29 pm    Post subject: Re: empty base class optimization Reply with quote



Thomas Mang wrote in news:410A03FC.5DD800A0 (AT) unet (DOT) univie.ac.at in
comp.lang.c++.moderated:

Quote:
Hello,

While reading another thread about sizeof base-classes, I ran the
following program on GCC 3.2

#include <iostream
#include struct a{};

struct b : public a{};

int main()
{
std::cout << sizeof(b) << "n";
std::cout << sizeof(b::a);
}

The output is:

1
1

so we se in the first case EBO during work. However, I am not sure the
second output is correct as the standard defines it. Yes, an object
must
practically have a size >= 1, but doen't the scope access operator
direclty request a base-class object of b with size 0 ?

Am I experiencing an restriction that is required, or is this a hole in
the standard (the b::a access, where sizeof(a) = 0 in the EBO case)?


No the EBO (Empty ...) is missleading. The Standard alows a base-class
that has no data members (and no virtuals) to share the same address as
another subobject with a distinct type.

In essence:

b binstance
(void *)&(a &)binstance == (void *)&binstance;

However if you write:

struct b: a
{
a ainstance;
};

Then:

(void *)&(a &)binstance != (void *)&binstance.ainstance;

I.e. the two 'a' subobjects must have a distinct address.

In fact none of the examples sofar exhibit EBO, all we have
is a derived class that "contains" a base class and *nothing*
else.

struct Empty {};
struct Another {};

struct EBO : Empty, Another {};

struct EBO2: Empty
{
char data;
};

struct EBO2 : Empty, Another
{
char data;
};

If you compiler supports EBO (and its enabled) all the above should
have a size of 1, compiler dependant alignment requirments aside Smile.

struct no_EBO : EBO, Empty
{
};

no_EBO should have size of 2 as it contains 2 "Empty" subobjects and
they are required to have a distinct address.

Rob.
--
http://www.victim-prime.dsl.pipex.com/

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

Back to top
Thomas Mang
Guest





PostPosted: Fri Jul 30, 2004 3:32 pm    Post subject: Re: empty base class optimization Reply with quote





Thomas Mang schrieb:

Quote:
Hello,

While reading another thread about sizeof base-classes, I ran the
following program on GCC 3.2

#include <iostream
#include struct a{};

struct b : public a{};

int main()
{
std::cout << sizeof(b) << "n";
std::cout << sizeof(b::a);
}

I apologize for a copy&pase error.
The real test program should read as following:


#include #include <ostream>


struct a{};

struct b : public a{char c;};


int main(int argc, char *argv[])
{
std::cout << "sizeof(a): " << sizeof(a) << "nsizeof(b): "
<< sizeof(b) << "nsizeof(b::a): " << sizeof(b::a);
return 0;
}



However, the issue remains the same: EBO is taking place, and b::a has
sizeof == 1.

regards,

Thomas

[ 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: Fri Jul 30, 2004 3:33 pm    Post subject: Re: empty base class optimization Reply with quote

In article <410A03FC.5DD800A0 (AT) unet (DOT) univie.ac.at>, Thomas Mang
<a9804814 (AT) unet (DOT) univie.ac.at> writes
Quote:
Hello,

While reading another thread about sizeof base-classes, I ran the
following program on GCC 3.2

#include <iostream
#include struct a{};

struct b : public a{};

int main()
{
std::cout << sizeof(b) << "n";
std::cout << sizeof(b::a);
}

The output is:

1
1

so we se in the first case EBO during work. However, I am not sure the
second output is correct as the standard defines it. Yes, an object must
practically have a size >= 1, but doen't the scope access operator
direclty request a base-class object of b with size 0 ?

Am I experiencing an restriction that is required, or is this a hole in
the standard (the b::a access, where sizeof(a) = 0 in the EBO case)?

The compiler is telling you the truth. You asked for the sizeof a,
albeit in the context of a b. It correctly told you the sizeof a. The
fact that the 'storage' for a overlaps that for b is of no concern to
the compiler. If you want something even more extreme try:

#include <iostream>
#include <ostream>
struct a{};
struct a1{};
struct b : public a, public a1{char c;};

int main()
{
std::cout << sizeof(b) << "n";
std::cout << sizeof(b::a);
std::cin.get();
}

Which still outputs (quite correctly)

1
1

The rule is very simply that padding bytes maybe recycled. However now
try:

#include #include <ostream>
struct a{};
struct b : public a {a ax;};

int main()
{
std::cout << sizeof(b) << "n";
std::cout << sizeof(b::a);
std::cin.get();
}

and the output is:
2
1

because the two instances of a (as a base and as a member) must have
distinct addresses.


--
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
Peter C. Chapin
Guest





PostPosted: Fri Jul 30, 2004 3:36 pm    Post subject: Re: empty base class optimization Reply with quote

Thomas Mang <a9804814 (AT) unet (DOT) univie.ac.at> wrote in news:410A03FC.5DD800A0
@unet.univie.ac.at:

Quote:
#include <iostream
#include struct a{};

struct b : public a{};

int main()
{
std::cout << sizeof(b) << "n";
std::cout << sizeof(b::a);
}

The output is:

1
1

Yes, I believe that sizeof(b::a) == sizeof(a). The namespace qualification
in this case only tells the compiler that you are talking about the type
'a' used as a base of 'b'. The type 'a' is defined above as an empty
struct, but it has a size > 0. The expression sizeof(b::a) does not in any
way refer to the size of the base subobject of b. Consider

struct X {
typedef int counter;
};

Now sizeof(X::counter) = sizeof(int), right? That fact that you are using
an int inside an X doesn't change the way sizeof works for int.

Peter

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

Back to top
Alberto Barbati
Guest





PostPosted: Fri Jul 30, 2004 3:37 pm    Post subject: Re: empty base class optimization Reply with quote

Thomas Mang wrote:

Quote:
so we se in the first case EBO during work. However, I am not sure the
second output is correct as the standard defines it. Yes, an object must
practically have a size >= 1, but doen't the scope access operator
direclty request a base-class object of b with size 0 ?

"b::a" is another way to say "a". The presence of the scope access
operator does not request the "base-class subobject of b of type a".
There is no way in C++ to actually refer to such entity as a type so you
can't get its size.

Alberto

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

Back to top
Dag Viken
Guest





PostPosted: Fri Jul 30, 2004 4:02 pm    Post subject: Re: empty base class optimization Reply with quote

"Thomas Mang" <a9804814 (AT) unet (DOT) univie.ac.at> wrote

Quote:
Hello,

While reading another thread about sizeof base-classes, I ran the
following program on GCC 3.2

#include <iostream
#include struct a{};

struct b : public a{};

int main()
{
std::cout << sizeof(b) << "n";
std::cout << sizeof(b::a);
}

The output is:

1
1

so we se in the first case EBO during work. However, I am not sure the
second output is correct as the standard defines it. Yes, an object must
practically have a size >= 1, but doen't the scope access operator
direclty request a base-class object of b with size 0 ?

Am I experiencing an restriction that is required, or is this a hole in
the standard (the b::a access, where sizeof(a) = 0 in the EBO case)?


I think it is a requirement of the C++ standard that all class and struct
objects must have nonzero size, base class or not. If you have an empty base
class with a derived class containing a single byte, both classes would be
of size 1. Like it or not.

Quote:

thank you,

Thomas


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

Back to top
Hyman Rosen
Guest





PostPosted: Sat Jul 31, 2004 3:43 am    Post subject: Re: empty base class optimization Reply with quote

Thomas Mang wrote:
Quote:
Am I experiencing an restriction that is required, or is this a hole in
the standard (the b::a access, where sizeof(a) = 0 in the EBO case)?

Your case exactly is described in 5.3.3/2. When applying sizeof to a
base class subobject, the result is the size of that object's type.

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

Back to top
Hyman Rosen
Guest





PostPosted: Sat Jul 31, 2004 3:48 am    Post subject: Re: empty base class optimization Reply with quote

Dag Viken wrote:
Quote:
I think it is a requirement of the C++ standard that all class and struct
objects must have nonzero size, base class or not. If you have an empty base
class with a derived class containing a single byte, both classes would be
of size 1. Like it or not.

No. All objects have a non-zero size, but empty base classes
may have zero size, as long as this would not place two such
classes of the same type atthe same address.

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

Back to top
Dag Viken
Guest





PostPosted: Sun Aug 01, 2004 11:04 am    Post subject: Re: empty base class optimization Reply with quote


"Hyman Rosen" <hyrosen (AT) mail (DOT) com> wrote

Quote:
Dag Viken wrote:
I think it is a requirement of the C++ standard that all class and
struct
objects must have nonzero size, base class or not. If you have an empty
base
class with a derived class containing a single byte, both classes would
be
of size 1. Like it or not.

No. All objects have a non-zero size, but empty base classes
may have zero size, as long as this would not place two such
classes of the same type atthe same address.


Yes, empty base classes may have zero size but still have sizeof() == 1.
Does a virtual base class have size zero?
I may be wrong but I am using VC7 and always get sizeof() >=1.

Dag


[ 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: Sun Aug 01, 2004 3:33 pm    Post subject: Re: empty base class optimization Reply with quote

In article <SDYOc.4861$9Y6.2244 (AT) newsread1 (DOT) news.pas.earthlink.net>, Dag
Viken <dag.viken (AT) earthlink (DOT) net> writes
Quote:
Yes, empty base classes may have zero size but still have sizeof() == 1.
Does a virtual base class have size zero?

Yes, but note that classes with virtual members are not empty (at least
using the current implementations of virtual)

Quote:
I may be wrong but I am using VC7 and always get sizeof() >=1.

--
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
John Torjo
Guest





PostPosted: Mon Aug 02, 2004 10:32 am    Post subject: Re: empty base class optimization Reply with quote

Francis Glassborow <francis (AT) robinton (DOT) demon.co.uk> wrote

Quote:
In article <SDYOc.4861$9Y6.2244 (AT) newsread1 (DOT) news.pas.earthlink.net>, Dag
Viken <dag.viken (AT) earthlink (DOT) net> writes
Yes, empty base classes may have zero size but still have sizeof() == 1.
Does a virtual base class have size zero?

If it's derived from, indeed it can have size zero.

Quote:

Yes, but note that classes with virtual members are not empty (at least
using the current implementations of virtual)

that is, sizeof(some_class) > 1, if the class has a virtual member -
which applies to virtual destructors as well.

So, if a base class has virtual members, the EBO is meaningless (there
is nothing to be optimized). Is that correct?

Best,
John


John Torjo
Freelancer
-- [email]john (AT) torjo (DOT) com[/email]

Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
-- http://www.torjo.com/win32gui/

Professional Logging Solution for FREE
-- http://www.torjo.com/code/logging.zip (logging - C++)
-- http://www.torjo.com/logview/ (viewing/filtering - Win32)
-- http://www.torjo.com/logbreak/ (debugging - Win32)
(source code available)

[ 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.