473,399 Members | 3,888 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

Base {}; sizeof(Base) == 1?

This may be stupid question, but why is sizeof(Base) == 1 in:

int main(int argc, char* argv[])
{
class Base
{
};
cout << sizeof(Base) << endl;
return 0;
}

I guess I want to know what the 1 byte is for? There is no vptr here,
so why 1 byte?I checked FAQ and couldn't find answer.

Aug 13 '06 #1
32 2116
* mo********@yahoo.com:
This may be stupid question, but why is sizeof(Base) == 1 in:

int main(int argc, char* argv[])
{
class Base
{
};
cout << sizeof(Base) << endl;
return 0;
}

I guess I want to know what the 1 byte is for? There is no vptr here,
so why 1 byte?I checked FAQ and couldn't find answer.
Needs a unique address.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Aug 13 '06 #2
In article <11*********************@m73g2000cwd.googlegroups. com>,
mo********@yahoo.com wrote:
This may be stupid question, but why is sizeof(Base) == 1 in:

int main(int argc, char* argv[])
{
class Base
{
};
cout << sizeof(Base) << endl;
return 0;
}

I guess I want to know what the 1 byte is for? There is no vptr here,
so why 1 byte?I checked FAQ and couldn't find answer.
class Base { };

int main() {
Base bases[2];
assert( &bases[0] != &bases[1] );
}

How could the compiler ensure the above assertion is true if sizeof(
Base ) was 0?
Aug 13 '06 #3
moleskyca1 posted:
This may be stupid question, but why is sizeof(Base) == 1 in:

int main(int argc, char* argv[])
{
class Base
{
};
cout << sizeof(Base) << endl;
return 0;
}

I guess I want to know what the 1 byte is for? There is no vptr here,
so why 1 byte?I checked FAQ and couldn't find answer.

To a large extent, C++ can be implemented in an "as if" way. Here's a
sample program which prints the integers 0 through 9:

#include <iostream>

using std::cout;

int main()
{
for(unsigned i = 0; i != 10; ++i)
{
cout << i << '\n';
}
}

In accordance with the C++ Standard, this program must print the integers 0
through 9... however it has much freedom in how it achieves this, just so
long as the program works "as if" it were coded the original way. For all
you know, the compiler may change it into:

cout << 0U << '\n';
cout << 1U << '\n';
cout << 2U << '\n';
cout << 3U << '\n';
cout << 4U << '\n';
cout << 5U << '\n';
cout << 6U << '\n';
cout << 7U << '\n';
cout << 8U << '\n';
cout << 9U << '\n';

Or perhaps even:

cout << "0\n1\n2\n3\n4\n5\n6\n7\n8\n9";

This "as if" principle gives compilers great freedom.

Every object (which is valid and has yet to be destroyed) must have a
unique address. For example:

struct MyStruct {};

int main()
{
MyStruct obj1;
MyStruct obj2;

assert(&obj1 != &obj2);
}

If every object must have a unique address, then the byte (or perhaps the
word) at that address cannot be used for anything else.

In accordance with this, "sizeof" might return 1, or maybe even 4.

However, in accordance with the "as if" principle, if you never take the
address of an object in any form, then there's no reason why it must
reserve memory. For instance, the compiler might change the following code:

struct A {};
struct B {};

void Func(A) {}
void Func(B) {}

int main()
{
A a; B b;

Func(a); Func(b);
}

into simply:

void FuncA() {}
void FuncB() {}

int main()
{
FuncA(); FuncB();
}

Lastly, "sizeof" shall never yield zero.

--

Frederick Gotham
Aug 13 '06 #4
Frederick Gotham posted:
If every object must have a unique address, then the byte (or perhaps
the word) at that address cannot be used for anything else.

Actually, if you define the object as const, then perhaps the compiler may
feel free to store its own personal data at that address (data which your
program knows nothing about...)

--

Frederick Gotham
Aug 13 '06 #5
Daniel T. wrote:
In article <11*********************@m73g2000cwd.googlegroups. com>,
mo********@yahoo.com wrote:
>This may be stupid question, but why is sizeof(Base) == 1 in:

int main(int argc, char* argv[])
{
class Base
{
};
cout << sizeof(Base) << endl;
return 0;
}

I guess I want to know what the 1 byte is for? There is no vptr here,
so why 1 byte?I checked FAQ and couldn't find answer.

class Base { };

int main() {
Base bases[2];
assert( &bases[0] != &bases[1] );
}

How could the compiler ensure the above assertion is true if sizeof(
Base ) was 0?
It could use infinitesimal pointer arithmetic: the size of an empty class
could be infinitesimally small. A pointers and sizeinformation would
contain an integer part and an infinitesimal part. Infinitesimal parts
would be ignored for allocation of memory, but they would be taken into
account for pointer arithmetic. The sizeof() operator would return the
integer part of a size.
Best

Kai-Uwe Bux
Aug 13 '06 #6

mo********@yahoo.com wrote:
This may be stupid question, but why is sizeof(Base) == 1 in:

int main(int argc, char* argv[])
{
class Base
{
};
cout << sizeof(Base) << endl;
return 0;
}
corrected:
___
# include <iostream>
#include <ostream>

class Base
{
};

int main()
{
Base base;
std::cout << sizeof( base ) << std::endl;
}
>
I guess I want to know what the 1 byte is for? There is no vptr here,
so why 1 byte?I checked FAQ and couldn't find answer.
It isn't neccessarily 1 byte, that depends on the platform.

Is base not an instance of type Base?
Does it not therefore reside somewhere in memory in a concrete
location?
what you see is the "this" parameter.
In otherwords, the programmer needs not track where base is because
that instance already knows where it is located in memory.

What if i defined Base like so...

class Base
{
int m_n;
public:
Base(int n) : m_n( n ) { }
~Base() { }
int get() const { return m_n; }
};

....how would the program know which Base is which?

int main()
{
Base base0( 10 );
Base base1( 20 );

std::cout << "base0 = " << base0.get() << std::endl;
std::cout << "base1 = " << base1.get() << std::endl;
}

There is only one get() function placed in memory.
However, get() receives the 'this' parameter - since get() is a member
function.
And that seemingly obscure this parameter is the key.
The call to get() therefore receives the instances' address
transparently.

Of course, you can make get() to be a non-member:

int get( Base* this) { return this->m_n; }

int main()
{
Base base( 1 );
std::cout << get( &base );
}

But all of a sudden, the encapsulated integer ( m_n) is no longer
private.
There is also a side-effect involved thats beyond the scope here.

The cost of that 1 extra byte you saw before solves a whole littany of
bugs and affords the programmer effective encapsulation + clear code.

Aug 14 '06 #7
Salt_Peter posted:
corrected:

It was just a code snippet -- no need for pedantry.

What if i defined Base like so...

class Base
{
int m_n;
public:
Base(int n) : m_n( n ) { }
~Base() { }
int get() const { return m_n; }
};

...how would the program know which Base is which?

This example has nothing to do with empty classes. Nonetheless, I would
expect the following to evaluate to true:

(void const*)&base == (void const*)&base.m_n

The cost of that 1 extra byte you saw before solves a whole littany of
bugs and affords the programmer effective encapsulation + clear code.

No it doesn't. The question was about empty classes, i.e.:

class MyClass {};

You've used examples which have member data... so *of course* their size
won't be zero.

--

Frederick Gotham
Aug 14 '06 #8
In article <eb**********@murdoch.acc.Virginia.EDU>, jk********@gmx.net
says...

[ ... ]
It could use infinitesimal pointer arithmetic: the size of an empty class
could be infinitesimally small. A pointers and sizeinformation would
contain an integer part and an infinitesimal part. Infinitesimal parts
would be ignored for allocation of memory, but they would be taken into
account for pointer arithmetic. The sizeof() operator would return the
integer part of a size.
How exactly would you do that without storing the "infinitesimal" part
as data in each object? If you did store it as data in the object, it
appears that on a typical machine it would have to be _larger_ than one
byte to distinguish more than 256 objects of that type. In fact, it
would generally be on the same general size as an address, which is
usually larger than a byte, by a factor of at least 2, often 4, and
sometimes 8.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Aug 14 '06 #9
In article <xK*******************@news.indigo.ie>, fg*******@SPAM.com
says...
Salt_Peter posted:
[ ... ]
class Base
{
int m_n;
public:
Base(int n) : m_n( n ) { }
~Base() { }
int get() const { return m_n; }
};
[ ... ]
This example has nothing to do with empty classes. Nonetheless, I would
expect the following to evaluate to true:

(void const*)&base == (void const*)&base.m_n
With an aggregate, that's basically guaranteed. As-is, there's a good
chance, but no certainty. At least with some implememtations, it would
NOT be true if Base contained any virtual functions.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Aug 14 '06 #10

"Alf P. Steinbach" <al***@start.nowrote in message news:4k************@individual.net...
* mo********@yahoo.com:
This may be stupid question, but why is sizeof(Base) == 1 in:

int main(int argc, char* argv[])
{
class Base
{
};
cout << sizeof(Base) << endl;
return 0;
}

I guess I want to know what the 1 byte is for? There is no vptr here,
so why 1 byte?I checked FAQ and couldn't find answer.

Needs a unique address.
struct Empty {};

C: sizeof(Empty) == 0
C++: sizeof(Empty) 0

Why doesn't C need a unique address?
--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Aug 14 '06 #11
"Alex Vinokur" <al****@users.sourceforge.netwrites:
"Alf P. Steinbach" <al***@start.nowrote in message
news:4k************@individual.net...
>* mo********@yahoo.com:
This may be stupid question, but why is sizeof(Base) == 1 in:

int main(int argc, char* argv[])
{
class Base
{
};
cout << sizeof(Base) << endl;
return 0;
}

I guess I want to know what the 1 byte is for? There is no vptr here,
so why 1 byte?I checked FAQ and couldn't find answer.

Needs a unique address.

struct Empty {};

C: sizeof(Empty) == 0
C++: sizeof(Empty) 0

Why doesn't C need a unique address?
In C,
struct Empty {};

is a syntax error. (Some compilers might support that as an
extension; if so, it's up to the compiler to decide what
sizeof(struct Empty) should be.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Aug 14 '06 #12

Keith Thompson wrote:
"Alex Vinokur" <al****@users.sourceforge.netwrites:
"Alf P. Steinbach" <al***@start.nowrote in message
news:4k************@individual.net...
* mo********@yahoo.com:
This may be stupid question, but why is sizeof(Base) == 1 in:

int main(int argc, char* argv[])
{
class Base
{
};
cout << sizeof(Base) << endl;
return 0;
}

I guess I want to know what the 1 byte is for? There is no vptr here,
so why 1 byte?I checked FAQ and couldn't find answer.

Needs a unique address.
struct Empty {};

C: sizeof(Empty) == 0
C++: sizeof(Empty) 0

Why doesn't C need a unique address?

In C,
struct Empty {};

is a syntax error. (Some compilers might support that as an
extension; if so, it's up to the compiler to decide what
sizeof(struct Empty) should be.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
What is the size of a in
int a[0];

Aug 14 '06 #13

Also, some compilers might/should optimize these empty classes if they
are
used as base classes for derived classes. In these cases, the
compiler might/should skip allocating that 1 byte.

Tolga Ceylan

Aug 14 '06 #14
swets wrote:
What is the size of a in
int a[0];
A zero size array is illegal according to ANSI C.
Igmar

Aug 14 '06 #15
Jerry Coffin wrote:
In article <eb**********@murdoch.acc.Virginia.EDU>, jk********@gmx.net
says...

[ ... ]
>It could use infinitesimal pointer arithmetic: the size of an empty class
could be infinitesimally small. A pointers and sizeinformation would
contain an integer part and an infinitesimal part. Infinitesimal parts
would be ignored for allocation of memory, but they would be taken into
account for pointer arithmetic. The sizeof() operator would return the
integer part of a size.

How exactly would you do that without storing the "infinitesimal" part
as data in each object? If you did store it as data in the object, it
appears that on a typical machine it would have to be _larger_ than one
byte to distinguish more than 256 objects of that type. In fact, it
would generally be on the same general size as an address, which is
usually larger than a byte, by a factor of at least 2, often 4, and
sometimes 8.
Infinitesimal parts would not need to be stored in the object, they would be
part of the address, i.e., pointers would be longer. However, since
infinitesimal parts can be ignored most of the time, it is very likely that
the compiler could optimize away that overhead for almost all types within
any given program.
Best

Kai-Uwe Bux
Aug 14 '06 #16
Jerry Coffin posted:
>This example has nothing to do with empty classes. Nonetheless, I would
expect the following to evaluate to true:

(void const*)&base == (void const*)&base.m_n

With an aggregate, that's basically guaranteed. As-is, there's a good
chance, but no certainty. At least with some implememtations, it would
NOT be true if Base contained any virtual functions.

If Base were a POD, then we'd have a guarantee. Since it's not, we don't.

--

Frederick Gotham
Aug 14 '06 #17
In article <eb**********@murdoch.acc.Virginia.EDU>, jk********@gmx.net
says...

[ ... ]
Infinitesimal parts would not need to be stored in the object, they would be
part of the address, i.e., pointers would be longer.
First of all, that doesn't strike me as changing much except the name
you give to where you store it -- you're still creating a unique address
for each object, just like you do right now. Under some circumstances
you choose to ignore that difference, but it mostly seems to result in
complexity with little or no benefit.

It seems to me there's a much more straighforward method: nearly all
modern systems support virtual memory anyway. Simply allocate a chunk of
address space without any backing storage. Empty objects get allocated
addresses without backing storage. Everything involved is then supported
quite directly by typical hardware.
However, since
infinitesimal parts can be ignored most of the time, it is very likely that
the compiler could optimize away that overhead for almost all types within
any given program.
Which (more likely than not) results in even further complexity or even
more wasted space. For example, consider a situation where we cast from
a pointer to derived to pointer to base, then back to pointer to derived
(where the base is empty). In this case, we apparently need to add the
"infinitesimal" part to the pointer during the cast to base, then strip
it back off during the cast to derived -- or else we need to build in
intelligence elsewhere to deal with the fact that a pointer to base may
not always include an infinitesimal part, so everything that looks at a
pointer to base needs to start by figuring out what kind of pointer it's
dealing with.

Except in rather limited situations, this doesn't gain us anything
anyway -- we're changing the terminology from treating the stored data
as part of the object to treating it as part of the pointer, but we're
still stuck with the fact that we're storing some data for each object
we create. Worse still, that's data that really needs to be stored,
using up real memory, whereas simply assigning a new address to each
object can be done without using any real memory to back those
addresses. Worst of all, the amount of data we have to store will
generally exceed the amount we'd use up even if we had backing storage
for each object and assigned each its own address.

The one place I can see this as a possible gain is if we have addresses
with quite a few (at least 20 or so) address bits that are stored but
not used. That, however, almost always means a processor that supports
virtual memory anyway, so it would support the much simpler version I've
outlined above.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Aug 14 '06 #18
mo********@yahoo.com wrote:
This may be stupid question, but why is sizeof(Base) == 1 in:

int main(int argc, char* argv[])
{
class Base
{
};
cout << sizeof(Base) << endl;
return 0;
}

I guess I want to know what the 1 byte is for? There is no vptr here,
so why 1 byte?I checked FAQ and couldn't find answer.
This is answered on Bjarne Stroustrup's FAQ:

http://www.research.att.com/~bs/bs_f...l#sizeof-empty

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Aug 14 '06 #19
In article <Fi*******************@news.indigo.ie>, fg*******@SPAM.com
says...

[ given code like: ]

(void const*)&base == (void const*)&base.m_n

[ ... where m_n is the first element in base ... ]
If Base were a POD, then we'd have a guarantee. Since it's not, we don't.
Actually, that's not quite true. Some of the things that most people
think are guaranteed by being a POD (and were probably intended to be
guaranteed) really aren't. For example:

struct XX {
int x;
public:
int y;
};

XX is a POD struct, but the presence of the access specifier (even
though it's vacuous) allows the compiler to rearrange x and y as it sees
fit.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Aug 14 '06 #20
Jerry Coffin posted:
struct XX {
int x;
public:
int y;
};

XX is a POD struct

Incorrect.

8.5.1/5

An aggregate is an array or a class with no user-declared constructors, no
private or protected non-static data members, no base classes, and no
virtual functions.

8.5.9/4

A POD-struct is an aggregate class that has no non-static data members of
type pointer to member, non-POD-struct, non-POD-union (or array of such
types) or reference, and has no user-defined copy assignment operator and no
user-defined destructor.

--

Frederick Gotham
Aug 14 '06 #21
Frederick Gotham wrote:
Jerry Coffin posted:
>struct XX {
int x;
public:
int y;
};

XX is a POD struct


Incorrect.

8.5.1/5

An aggregate is an array or a class with no user-declared constructors, no
private or protected non-static data members, no base classes, and no
virtual functions.

8.5.9/4

A POD-struct is an aggregate class that has no non-static data members of
type pointer to member, non-POD-struct, non-POD-union (or array of such
types) or reference, and has no user-defined copy assignment operator and no
user-defined destructor.
And what about struct XX violates this definition?
Aug 15 '06 #22
Mark P posted:
>Incorrect.

8.5.1/5

An aggregate is an array or a class with no user-declared constructors,
no private or protected non-static data members, no base classes, and
no virtual functions.

8.5.9/4

A POD-struct is an aggregate class that has no non-static data members
of type pointer to member, non-POD-struct, non-POD-union (or array of
such types) or reference, and has no user-defined copy assignment
operator and no user-defined destructor.

And what about struct XX violates this definition?

Read it slowly and carefully. Twice.

--

Frederick Gotham
Aug 15 '06 #23
Frederick Gotham wrote:
Mark P posted:
Incorrect.

8.5.1/5

An aggregate is an array or a class with no user-declared constructors,
no private or protected non-static data members, no base classes, and
no virtual functions.

8.5.9/4

A POD-struct is an aggregate class that has no non-static data members
of type pointer to member, non-POD-struct, non-POD-union (or array of
such types) or reference, and has no user-defined copy assignment
operator and no user-defined destructor.
And what about struct XX violates this definition?


Read it slowly and carefully. Twice.
I did -- and I don't get your point either.

struct XX is a POD that does not have any user declared ctors, does not
have any private or protected non-static data members, does not have a
baseclass and does not sport any virtual functions -- which makes it an
aggregate.

Further more it does not have any non-static data members of type
pointer to member, non-POD-struct, non-POD-union (or array of such
types) or reference, and does not have any user-defined copy assignment
operator and contains no user-defined dtor either.

There.. what am I missing?

Aug 15 '06 #24
Dilip posted:
>Read it slowly and carefully. Twice.

I did -- and I don't get your point either.

struct XX is a POD that does not have any user declared ctors, does not
have any private or protected non-static data members, does not have a
baseclass and does not sport any virtual functions -- which makes it an
aggregate.

Further more it does not have any non-static data members of type
pointer to member, non-POD-struct, non-POD-union (or array of such
types) or reference, and does not have any user-defined copy assignment
operator and contains no user-defined dtor either.

There.. what am I missing?

Reading comprehension skills.

Read it slowly and carefully again.

HINT: The second definition refers to the first.

--

Frederick Gotham
Aug 15 '06 #25
Frederick Gotham posted:
HINT: The second definition refers to the first.

Apologies, I got two examples mixed up. The following is definitely not a
POD, because "a" is private:

class MyStruct {

int a;

public:

int b;

};

But as for the the following:

struct MyStruct {

int a;

public:

int b;

};

, I would have thought that the access specifier made no difference. What
part of the Standard indicates that a class or struct is *not* a POD if its
definition contains access specifiers?

If it's a POD, then its members must be in the order as their defined in
the struct or class definition.

--

Frederick Gotham
Aug 15 '06 #26
In article <fC*******************@news.indigo.ie>, fg*******@SPAM.com
says...

[ ... ]
But as for the the following:

struct MyStruct {

int a;

public:

int b;

};

, I would have thought that the access specifier made no difference.
....but you'd be wrong, just like all of us were for years. AFAIK, I was
the first to notice this particular anomaly, and that was only a few
months ago, after having studied the standard in considerable detail for
years (all the way back to publicly released committed drafts, long
before it WAS a standard).
What
part of the Standard indicates that a class or struct is *not* a POD if its
definition contains access specifiers?
Nothing. As I said, the example given IS a POD struct, because it meets
all the requirements to be a POD struct.
If it's a POD, then its members must be in the order as their defined in
the struct or class definition.
For better or worse, that's just not true. According to section 9.2/12:
"The order of allocation of nonstatic data members separated by an
access-specifier is unspecified (11.1)."

As I said before, much of what most people _think_ is required of a POD
struct really isn't.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Aug 15 '06 #27
Jerry Coffin wrote:
In article <eb**********@murdoch.acc.Virginia.EDU>, jk********@gmx.net
says...

[ ... ]
>Infinitesimal parts would not need to be stored in the object, they would
be part of the address, i.e., pointers would be longer.

First of all, that doesn't strike me as changing much except the name
you give to where you store it -- you're still creating a unique address
for each object, just like you do right now. Under some circumstances
you choose to ignore that difference, but it mostly seems to result in
complexity with little or no benefit.

It seems to me there's a much more straighforward method: nearly all
modern systems support virtual memory anyway. Simply allocate a chunk of
address space without any backing storage. Empty objects get allocated
addresses without backing storage. Everything involved is then supported
quite directly by typical hardware.
That is an interesting idea.
>However, since
infinitesimal parts can be ignored most of the time, it is very likely
that the compiler could optimize away that overhead for almost all types
within any given program.

Which (more likely than not) results in even further complexity or even
more wasted space. For example, consider a situation where we cast from
a pointer to derived to pointer to base, then back to pointer to derived
(where the base is empty). In this case, we apparently need to add the
"infinitesimal" part to the pointer during the cast to base, then strip
it back off during the cast to derived -- or else we need to build in
intelligence elsewhere to deal with the fact that a pointer to base may
not always include an infinitesimal part, so everything that looks at a
pointer to base needs to start by figuring out what kind of pointer it's
dealing with.

Except in rather limited situations, this doesn't gain us anything
anyway -- we're changing the terminology from treating the stored data
as part of the object to treating it as part of the pointer, but we're
still stuck with the fact that we're storing some data for each object
we create. Worse still, that's data that really needs to be stored,
using up real memory, whereas simply assigning a new address to each
object can be done without using any real memory to back those
addresses. Worst of all, the amount of data we have to store will
generally exceed the amount we'd use up even if we had backing storage
for each object and assigned each its own address.

The one place I can see this as a possible gain is if we have addresses
with quite a few (at least 20 or so) address bits that are stored but
not used. That, however, almost always means a processor that supports
virtual memory anyway, so it would support the much simpler version I've
outlined above.
Ok, so now we have already two ways of how a compiler could guarantee
uniqueness of addresses for objects without requiring the size of an empty
class to be at least 1. Keep in mind that my original suggestion was just
to answer the (rhetorical) question:
class Base { };

int main() {
Base bases[2];
assert( &bases[0] != &bases[1] );
}

How could the compiler ensure the above assertion is true if sizeof(
Base ) was 0?
I have no opinion on whether using any of the schemes devised by either of
us would be more or less efficient than the simple and straight forward
scheme the standard suggests. I just wanted to point out that there is no
necessity in the sizeof(Base)>0 requirement. The requirement is not there
to make things *possible* it is there to make them *simple*.
Best

Kai-Uwe Bux
Aug 15 '06 #28
Jerry Coffin posted:

For better or worse, that's just not true. According to section 9.2/12:
"The order of allocation of nonstatic data members separated by an
access-specifier is unspecified (11.1)."

As I said before, much of what most people _think_ is required of a POD
struct really isn't.

Seems like a "bug" in the Standard to me, arising out of a technicality.

Thankfully though it shouldn't be a problem, because we've no reason to place
the redundant access-specifier in there.

--

Frederick Gotham
Aug 15 '06 #29
In article <F3*******************@news.indigo.ie>, fg*******@SPAM.com
says...

[ ... ]
Seems like a "bug" in the Standard to me, arising out of a technicality.
That's undoubtedly correct -- simply a possibility (and I'll openly
admit, an unusual one) the committee members didn't consider.
Thankfully though it shouldn't be a problem, because we've no reason to place
the redundant access-specifier in there.
Unfortunately, I'm not quite so sanguine about that -- while a person
probably wouldn't put the access specifier there, I can easily imagine a
code generator putting in access specifiers that weren't strictly
necessary (in fact, I know of some that already do so).

--
Later,
Jerry.

The universe is a figment of its own imagination.
Aug 15 '06 #30

"Jerry Coffin" <jc*****@taeus.comskrev i meddelandet
news:MP************************@news.sunsite.dk...
In article <F3*******************@news.indigo.ie>,
fg*******@SPAM.com
says...

[ ... ]
>Seems like a "bug" in the Standard to me, arising out of a
technicality.

That's undoubtedly correct -- simply a possibility (and I'll openly
admit, an unusual one) the committee members didn't consider.
I think they might very well have considered the case, but simply not
wanted to add "except for redundant public specifiers" to the
complicated rules.
>
>Thankfully though it shouldn't be a problem, because we've no
reason to place
the redundant access-specifier in there.

Unfortunately, I'm not quite so sanguine about that -- while a
person
probably wouldn't put the access specifier there, I can easily
imagine a
code generator putting in access specifiers that weren't strictly
necessary (in fact, I know of some that already do so).
Then we have better fix them, rather than changing the language to
accomodate buggy programs. :-)

The C++ language inherits PODs from the C language. As soon as we add
access specifiers to a structure, we have already left C land so they
are not PODs anymore.

The thing is that some structures are guaranteed to be compatible with
C. We call them PODs. Some other structures just *might* be compatible
as well, we just don't have any guarantees.

Seeing that the C++0x draft is already over 1000 pages long, I don't
think we need any more corner cased added to it.
Bo Persson
Aug 15 '06 #31
In article <eb**********@murdoch.acc.Virginia.EDU>, jk********@gmx.net
says...

[ ... ]
Ok, so now we have already two ways of how a compiler could guarantee
uniqueness of addresses for objects without requiring the size of an empty
class to be at least 1.
Actually no. What I'd advocated using memory management hardware would
still give 1 as the size of the object -- each object would be given a
unique address just like usual. The difference would be that it wouldn't
actually consume any real _memory_ for the object, because no memory
would be associated with those addresses.

[ ... ]
I have no opinion on whether using any of the schemes devised by either of
us would be more or less efficient than the simple and straight forward
scheme the standard suggests. I just wanted to point out that there is no
necessity in the sizeof(Base)>0 requirement. The requirement is not there
to make things *possible* it is there to make them *simple*.
It also keeps things predictable. Just for one obvious situation that
inevitably arises, consider what happens when you convert a pointer to
an integer type and back. I realize that at this point you no longer
have portable code -- but (unlike Java) C++ has never attempted to
forbid non-portable code or anything like that.

Anyway, in the end you're basically right: the situation undoubtedly
could be handled in some other way, but it's probably not worth spending
a lot more time on it either.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Aug 18 '06 #32
In article <4k************@individual.net>, bo*@gmb.dk says...

[ ... ]
That's undoubtedly correct -- simply a possibility (and I'll openly
admit, an unusual one) the committee members didn't consider.

I think they might very well have considered the case, but simply not
wanted to add "except for redundant public specifiers" to the
complicated rules.
From the discussions I've seen between committee members on
comp.std.c++, I _seriously_ doubt that's the case. I've always gotten
the distinct impression that they want the standard to be as complete
and accurate as possible, and are willing to put almost inordinate
effort into ensuring that even strange corner cases be specified
correctly.

My guess is that with a bit of care, the rules could be reworded to fit
this requirement in fairly naturally -- e.g. to say that in a POD
struct, there may be no access specifier between any two variable
declarations.
Unfortunately, I'm not quite so sanguine about that -- while a
person probably wouldn't put the access specifier there, I can
easily imagine a code generator putting in access specifiers
that weren't strictly necessary (in fact, I know of some that
already do so).

Then we have better fix them, rather than changing the language to
accomodate buggy programs. :-)
They're not buggy. They produce code that's absolutely correct -- and
the ones I've seen put the redundant access specifiers there for a
reason: they're (generally) placeholders with comments telling you what
kinds of things to put in each section. They put a framework in place,
and explicitly put in "blank" spots for you to fill in the details.

Sometimes, however, you don't need to fill in every detail, which can
leave a redundant access specifier.
The C++ language inherits PODs from the C language. As soon as we add
access specifiers to a structure, we have already left C land so they
are not PODs anymore.
Not really true -- C+++ "inherits" a form of struct from C, and that
form is a POD. As is perfectly rasonable in inheritance, however, C++
also extends the definition of POD somewhat, adding a considerable
number of things that aren't directly available in C. Nonetheless, the
intent is clearly that these remain layout-compatible with some similar
struct in C.
The thing is that some structures are guaranteed to be compatible with
C. We call them PODs. Some other structures just *might* be compatible
as well, we just don't have any guarantees.
The problem is that right now, a POD struct isn't guaranteed to be
compatible with C either.
Seeing that the C++0x draft is already over 1000 pages long, I don't
think we need any more corner cased added to it.
Maybe not. Then again, there are times that fixing something actually
makes the result shorter and simpler...

--
Later,
Jerry.

The universe is a figment of its own imagination.
Aug 18 '06 #33

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Gopal-M | last post by:
I have the problem with sizeof operator I also want to implement a function that can return size of an object. My problem is as follows.. I have a Base class, say Base and there are many class...
7
by: Alex Vinokur | last post by:
"Alf P. Steinbach" <alfps@start.nowrote in message news:4k9755Fb3nt6U1@individual.net... struct Empty {}; C: sizeof(Empty) == 0 C++: sizeof(Empty) 0 Why doesn't C need a unique address?
7
by: Yen Kwoon | last post by:
Note: This problem is related to gcc but after some back and forth in group gnu.gcc.help it seems to have morph into more of a c++ specificiation question, hence the transplanting to this group. ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.