 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Thomas Mang Guest
|
Posted: Fri Jul 30, 2004 9:54 am Post subject: empty base class optimization |
|
|
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
|
Posted: Fri Jul 30, 2004 3:29 pm Post subject: Re: empty base class optimization |
|
|
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 .
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
|
Posted: Fri Jul 30, 2004 3:32 pm Post subject: Re: empty base class optimization |
|
|
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
|
Posted: Fri Jul 30, 2004 3:33 pm Post subject: Re: empty base class optimization |
|
|
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
|
Posted: Fri Jul 30, 2004 3:36 pm Post subject: Re: empty base class optimization |
|
|
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
|
Posted: Fri Jul 30, 2004 3:37 pm Post subject: Re: empty base class optimization |
|
|
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
|
Posted: Fri Jul 30, 2004 4:02 pm Post subject: Re: empty base class optimization |
|
|
"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.
[ 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
|
Posted: Sat Jul 31, 2004 3:43 am Post subject: Re: empty base class optimization |
|
|
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
|
Posted: Sat Jul 31, 2004 3:48 am Post subject: Re: empty base class optimization |
|
|
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
|
Posted: Sun Aug 01, 2004 11:04 am Post subject: Re: empty base class optimization |
|
|
"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
|
Posted: Sun Aug 01, 2004 3:33 pm Post subject: Re: empty base class optimization |
|
|
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
|
Posted: Mon Aug 02, 2004 10:32 am Post subject: Re: empty base class optimization |
|
|
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 |
|
 |
|
|
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
|
|