Topic: [Q] Why no ctors on aggregates?


Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1999/02/04
Raw View
sellis@geocities.com (Sean Ellis) writes:

>clamage@Eng.Sun.COM (Steve Clamage) wrote:

>>Since we are concerned only about C compatibility for aggregates
>>and PODs, we allow only those C++ features that have no interaction
>>with C semantics. Constructors don't pass that test.

>So: PODs are defined for compatibility with C, which is fair enough.

>However, they are the only objects that I can see for which
>layout-compatibility is guaranteed.

Right. The purpose of providing the notion of "POD" in C++ is
to define areas of the language where C code continues to be
valid and have the same meaning in C++. The idea is to let C
code continue to be used in C++ where possible, but not
necessarily to allow you to get C semantics when using C++
features not found in C.

>To elaborate - what I am trying to do is to "wrap up" the built-in
>types so that they are all a particular size (in this case, 64 bits),
>so the solution I came up with was something like this:

>union PaddedInt
>{
> PaddedInt(int Value) : m_Value(Value) {}
> int  operator int() {return(m_Value);}

> int m_Value;
> __int64 m_Padding;
>};

>union PaddedChar
>{
> PaddedChar(charValue) : m_Value(Value) {}
> char  operator char() {return(m_Value);}

> char m_Value;
> __int64 m_Padding;
>};

>...etc...

>(These could easily be templatised, but that's a side issue.)

>AFAICT, these would be POD-unions apart from the presence of the
>ctors. Can I guarantee that the ctors will not affect the layout,
>size, etc. of the data? From the spec, it appears that the answer is
>"no, you can't", but why not?

No guarantee is made that the constructors won't affect layout,
but it unlikely that they will. The restrictions on PODs are not
intended to prevent you from writing this code; that's just a side
effect. The problem is that the presence of a user-written
constructor affects the semantics of creating or copying class
objects.  Instead of making a bunch of special cases ("if you have
this kind of constructor it's a POD, but not if you have that kind"),
we have the simpler rule, "no user-defined constructors".

That said, I don't think you have much of a problem anyway.

If you remove the constructors, you have a POD, because the
non-virtual type-conversion operators don't affect POD-ness.
Since you have a PID-union, in many places where you create
a Padded object you can use brace-initialization:
 PaddedInt j = { 42 }; // sets j.m_Value

There are a few places where you can use a constructor but
not brace initialization, as in creating explicit temps.
Perhaps you can work around those places.

--
Steve Clamage, stephen.clamage@sun.com


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sellis@geocities.com (Sean Ellis)
Date: 1999/02/02
Raw View
I've had a poke around in the FAQ, and used Deja news to go through a
bunch of old posts, and I haven't found the answer to this question
anywhere:

* Why are constructors prohibited on aggregate types
 (and therefore on POD types)?

AFAICT, a ctor is just a weirdly named non-virtual member function,
and since other non-virtual member functions are allowed on aggregates
and PODs, the ctor should be allowed also.

I'm obviously missing something - does anyone know what it is?


Sean

|||||||| 012345678 Proportiometer(TM)
######## ^  [Non spammers: Delete "un-" after @ in reply-to field]
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/02/02
Raw View
In article <36b6c07d.1129634@news.uk.superscape.com>, Sean Ellis
<sellis@geocities.com> writes
>*      Why are constructors prohibited on aggregate types
>       (and therefore on POD types)?

They aren't:) because all objects are notionally constructed in C++.
However they are required to be default ctors, i.e. ones that construct
the object without any data.  As to POD types, these are types that are
necessarily compatible with C-structs etc. for which there are no such
things as ctors.
>
>AFAICT, a ctor is just a weirdly named non-virtual member function,
>and since other non-virtual member functions are allowed on aggregates
>and PODs, the ctor should be allowed also.

A ctor has weird behaviour:) it is the only type of function that can be
run on an object before it exists and cannot be run on one that does.
No other function has the run once property.

>
>I'm obviously missing something - does anyone know what it is?

Francis Glassborow      Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1999/02/02
Raw View
sellis@geocities.com (Sean Ellis) writes:

>I've had a poke around in the FAQ, and used Deja news to go through a
>bunch of old posts, and I haven't found the answer to this question
>anywhere:

>* Why are constructors prohibited on aggregate types
> (and therefore on POD types)?

You've got it backwards. If a type has a user-defined constructor
or destructor, it is not an aggregate, by definition.

The term aggregate is defined in order specify certain kinds of C
compatibility. The term POD ("Plain Old Data") is defined in order
to specify stricter kinds of C compatibility.

An aggregate is a type that has properties that allow certain
operations to proceed exactly as they do in C. In particular,
you can use brace-initialization.

But if a class has a user-defined constructor, it must be assumed
that the constructor is necessary for initialization, and the compiler
cannot just assign values to data members. Once you reach that
point, the brace-initialization rules break down. In simple cases
they might still apply, but in typical cases the brace-initialization
rules don't work.

Since we are concerned only about C compatibility for aggregates
and PODs, we allow only those C++ features that have no interaction
with C semantics. Constructors don't pass that test.

--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sellis@geocities.com (Sean Ellis)
Date: 1999/02/03
Raw View
clamage@Eng.Sun.COM (Steve Clamage) wrote:

>[...]
>
>Since we are concerned only about C compatibility for aggregates
>and PODs, we allow only those C++ features that have no interaction
>with C semantics. Constructors don't pass that test.

So: PODs are defined for compatibility with C, which is fair enough.

However, they are the only objects that I can see for which
layout-compatibility is guaranteed.

To elaborate - what I am trying to do is to "wrap up" the built-in
types so that they are all a particular size (in this case, 64 bits),
so the solution I came up with was something like this:

union PaddedInt
{
 PaddedInt(int Value) : m_Value(Value) {}
 int  operator int() {return(m_Value);}

 int m_Value;
 __int64 m_Padding;
};

union PaddedChar
{
 PaddedChar(charValue) : m_Value(Value) {}
 char  operator char() {return(m_Value);}

 char m_Value;
 __int64 m_Padding;
};

...etc...

(These could easily be templatised, but that's a side issue.)

AFAICT, these would be POD-unions apart from the presence of the
ctors. Can I guarantee that the ctors will not affect the layout,
size, etc. of the data? From the spec, it appears that the answer is
"no, you can't", but why not?


Sean

|||||||| 012345678 Proportiometer(TM)
######## ^  [Non spammers: Delete "un-" after @ in reply-to field]


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]