Topic: Order of data members?


Author: lisa_lippincott@advisories.com (Lisa Lippincott)
Date: 1998/12/15
Raw View

AllanW@my-dejanews.com wrote:

> The current rule also allows C++ to communicate with:
>     - Files with fixed-length records
>     - Functions in other languages that access shared structures
>     - Hardware devices with specific layouts in memory

It does and it doesn't.  The current rule allows compilers to pad,
but not rearrange members.  As I see it, there are three kinds of
structures we use:

   structures as described above, where the programmer requires
   an exact layout;

   structures which the compiler is completely free to rearrange,
   pack, and pad; and

   structures which may be rearranged, packed, or padded, but only
   in accordance with a particular binary interface specification.
   (So that code can link to libraries compiled under other
   circumstances.)

As I see it, the C and C++ rules try to split the difference,
and are less than ideal in all cases.  But we muddle through
as best we can.

                                           --Lisa Lippincott


[ 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: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/12/15
Raw View
On 14 Dec 1998 22:23:08 GMT, AllanW@my-dejanews.com

>        private::    // :: means okay to rearrange data in this section

Don't know if you are joking or not.  In any case, it is easy to
forget the extra ":" and write "private:" where "private::" would
have been what we wanted.


--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ 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: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/12/15
Raw View
In article <753v25$kfn$1@nnrp1.dejanews.com>,  <AllanW@my-dejanews.com> wrote:
>
>A few days ago I was thinking, "AllanW," -- I call myself AllanW because
>that's who I am -- "The :: token doesn't have enough meanings already. We
>should try to find something else to do with it." This may qualify. :^]
>
>    class X {
>        public:      // Normal public members
>            X();
>        private::    // :: means okay to rearrange data in this section
>            char a;
>            int  b;  // Most systems would move b first
>            char c;
>    };
>
>Of course, it doesn't make sense to *REQUIRE* a compiler to rearrange
>data in an implementation-defined manner. So the compiler is free to
>ignore the extra colen, but it's there as an optimization hint for
>compilers that understand it.

Currently you can achieve the same effect with:

class X {
        public: X();
        private:char a;
        private:int  b;  // Most systems would move b first
        private:char c;
};

This allows the compiler to rearrange the members any way they want,
without introducing a new key-word.

Since other new good (and IMO more important such as base::) suggestions
were rejected because it was possible to achieve them without changing
the language I would find it odd to add private:: (or similar keywords).

Programmers from some other languages might even prefer this form
(no need to search for the access-specifier).


--
// Home page  http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]




[ 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: AllanW@my-dejanews.com
Date: 1998/12/15
Raw View
In article <lisa_lippincott-1412981803400001@38.168.253.3>,
  lisa_lippincott@advisories.com (Lisa Lippincott) wrote:
>
>
> AllanW@my-dejanews.com wrote:
>
> > The current rule also allows C++ to communicate with:
> >     - Files with fixed-length records
> >     - Functions in other languages that access shared structures
> >     - Hardware devices with specific layouts in memory
>
> It does and it doesn't.  The current rule allows compilers to pad,
> but not rearrange members.

Those rules don't *always* conflict! Put big built-in types
    long id;
before the small ones
    char name[50]; // char is smaller than long
and your risk of padding is very slight indeed.

> As I see it, there are three kinds of
> structures we use:
>
>    structures as described above, where the programmer requires
>    an exact layout;

Required for I/O and for non-C++ programs.

>    structures which the compiler is completely free to rearrange,
>    pack, and pad; and

Used for data manipulated within C++ only. The as-if rule should
apply here.

>    structures which may be rearranged, packed, or padded, but only
>    in accordance with a particular binary interface specification.

Not sure I understand this one. The compiler can rearrange it, but
only according to certain rules? Why not rearrange it in source code
instead?

>    (So that code can link to libraries compiled under other
>    circumstances.)

But if that library code was C++ (or assembly language designed to
interface with this version of C++), it would fall into the second
case for maximum efficiency. And if it was some other language, it
would fall into the first case -- surely you can't share a structure
unless you agree on the exact layout. I still don't understand the
"certain rules" of which you speak.

> As I see it, the C and C++ rules try to split the difference,
> and are less than ideal in all cases.  But we muddle through
> as best we can.

As I see it, a structure with no access modifiers matches the
first kind, and anything else matches the second.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ 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: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1998/12/13
Raw View
On 10 Dec 1998 20:46:40 GMT, AllanW@my-dejanews.com
>  sbnaran@uiuc.edu wrote:

>> ... the way I would change the standard is this: the order of
>> data members is completely unspecified (even if they all fall within
>> the same access specifier).  This is because layout order is an
>> implementation detail, and if the optimizer can find a better layout
>> -- eg, one that results in faster access or less padding -- then
>> let it do so.  And furthermore, padding at the left should be
>> allowed too.  I guess the current rule about padding on left and
>> order of data members is for backward compatibility with C, right?


>For starters.

Fine.


>But your proposed rule would also break existing C++ (not just C)
>programs. It takes away the ability for C++ to access low-level
>constructs.
>
>The current rule also allows C++ to communicate with:
>    - Files with fixed-length records
>    - Functions in other languages that access shared structures
>    - Hardware devices with specific layouts in memory

Didn't think of these.  But here's an idea.  If we want no
rearranging, then we use a special keyword.  Let's
assume sizeof(short)==2 and sizeof(int)==4.

struct Alpha
{
     literal_order
     {
          short a;
          int b;
          short c;
     }
}; // sizeof==12 (a, 2 bytes, b, c, 2 bytes)

struct Beta
{
     short a;
     int b;
     short c;
}; // sizeof==8 (a, c, b)


Even if this rule were adopted, it would be annoying to those who
have to change their code.  If they forget to change one struct,
the code still compiles, but with the wrong results.

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ 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: James Kuyper <kuyper@wizard.net>
Date: 1998/12/13
Raw View
Siemel Naran wrote:
....
> >The current rule also allows C++ to communicate with:
> >    - Files with fixed-length records
> >    - Functions in other languages that access shared structures
> >    - Hardware devices with specific layouts in memory
>
> Didn't think of these.  But here's an idea.  If we want no
> rearranging, then we use a special keyword.  Let's
> assume sizeof(short)==2 and sizeof(int)==4.

You can't achieve backwards compatibility by requiring a new keyword to
get the old behavior.


[ 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: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/12/14
Raw View
On 13 Dec 1998 18:30:47 GMT, James Kuyper <kuyper@wizard.net> wrote:
>Siemel Naran wrote:

>> Didn't think of these.  But here's an idea.  If we want no
>> rearranging, then we use a special keyword.  Let's
>> assume sizeof(short)==2 and sizeof(int)==4.

>You can't achieve backwards compatibility by requiring a new keyword to
>get the old behavior.

Right.  Moreover, if the new keyword were adopted, the old code would
continue to compile even if it weren't changed (ie, the compiler won't
give a warning or error) and this is bad.  At least an error or warning
would be better as the programmers could change the code for the new
rule.

So how about this.  If our class has more than one access specifier
in it, then the compiler is free to order the data any way it wants.
So good old POD structs remain unaffected.

class X
{
     public:
          X();
     private:
          char a; int b; char c;
};

I don't like this idea so much because it doesn't seem very natural.


So how about if an access region has the same keyword two times in a
row, then the compiler can order the data members anyway it sees fit.

class X
{
     public:
          X();
     private: private:
          char a; int b; char c;
};

Seems a little better.


--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ 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: AllanW@my-dejanews.com
Date: 1998/12/14
Raw View
In article <slrn778ga9.go4.sbnaran@fermi.ceg.uiuc.edu>,
  sbnaran@KILL.uiuc.edu wrote:
>
> On 13 Dec 1998 18:30:47 GMT, James Kuyper <kuyper@wizard.net> wrote:
> >Siemel Naran wrote:
>
> >> ... here's an idea.  If we want no
> >> rearranging, then we use a special keyword.  Let's
> >> assume sizeof(short)==2 and sizeof(int)==4.
>
> >You can't achieve backwards compatibility by requiring a new keyword to
> >get the old behavior.
>
> Right.  Moreover, if the new keyword were adopted, the old code would
> continue to compile even if it weren't changed (ie, the compiler won't
> give a warning or error) and this is bad.  At least an error or warning
> would be better as the programmers could change the code for the new
> rule.
>
> So how about this.  If our class has more than one access specifier
> in it, then the compiler is free to order the data any way it wants.
> So good old POD structs remain unaffected.
>
> class X
> {
>      public:
>           X();
>      private:
>           char a; int b; char c;
> };
>
> I don't like this idea so much because it doesn't seem very natural.
>
> So how about if an access region has the same keyword two times in a
> row, then the compiler can order the data members anyway it sees fit.
>
> class X
> {
>      public:
>           X();
>      private: private:
>           char a; int b; char c;
> };
>
> Seems a little better.

A code generator might generate this today, without any special meaning.

A few days ago I was thinking, "AllanW," -- I call myself AllanW because
that's who I am -- "The :: token doesn't have enough meanings already. We
should try to find something else to do with it." This may qualify. :^]

    class X {
        public:      // Normal public members
            X();
        private::    // :: means okay to rearrange data in this section
            char a;
            int  b;  // Most systems would move b first
            char c;
    };

Of course, it doesn't make sense to *REQUIRE* a compiler to rearrange
data in an implementation-defined manner. So the compiler is free to
ignore the extra colen, but it's there as an optimization hint for
compilers that understand it.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ 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: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/10
Raw View
sbnaran@localhost.localdomain.COM (Siemel Naran) writes:

>I guess the current rule about padding on left and
>order of data members is for backward compatibility with C, right?

Yes. C makes guarantees about member layout in structs. If C++
doesn't make the same guarantees for PODs, you could not write
a C++ struct compatible with C code that used the same struct
definition.

One way around that would be to extend the use of language
linkage so that
 extern "C" struct S { ... };
would mean that the layout of S follows C rules if S is a POD.
That would cause a change in meaning of some programs, however.
Example 1:
 extern "C" struct S { char c; int j; } s;
Example 2:
 struct S { char c; int j; };
 extern "C" S s;

Under current rules, the two examples mean the same thing:
S is a struct, and s has C linkage.

Under the proposed rules, the two examples would have a
different meaning: In example 1, S follows C layout rules,
but in example 2 it need not.

--
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: AllanW@my-dejanews.com
Date: 1998/12/10
Raw View
In article <slrn76u9at.neb.sbnaran@localhost.localdomain>,
  sbnaran@uiuc.edu wrote:
> ... the way I would change the standard is this: the order of
> data members is completely unspecified (even if they all fall within
> the same access specifier).  This is because layout order is an
> implementation detail, and if the optimizer can find a better layout
> -- eg, one that results in faster access or less padding -- then
> let it do so.  And furthermore, padding at the left should be
> allowed too.  I guess the current rule about padding on left and
> order of data members is for backward compatibility with C, right?

For starters.

But your proposed rule would also break existing C++ (not just C)
programs. It takes away the ability for C++ to access low-level
constructs.

The current rule also allows C++ to communicate with:
    - Files with fixed-length records
    - Functions in other languages that access shared structures
    - Hardware devices with specific layouts in memory
Your rule would make all of these quite difficult. Sure, we could
still simulate structure layouts by building them one element at a
time with memcpy -- but this would be slow and error-prone to
write, and slow to execute.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ 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: David R Tribble <david.tribble@dallas.beasys.com>
Date: 1998/12/09
Raw View
I think it would be reasonable to allow structs containing members
having identical access-specifiers to be equivalent regardless of
the number or placement of the access-specifiers.  For example, all
of these should, in my mind, be considered equivalent:

    struct S1
    {
        int  a;
        int  b;
        int  c;
    };

    struct S2
    {
        int  a;
    public:
        int  b;
        int  c;
    };

    struct S3
    {
    public:
        int  a;
    public:
        int  b;
    public:
        int  c;
    };

I can't think of a reason why this would unduly complicate
compilers.  I also see no particular usefulness in considering
them as structs with differently-ordered members.

Changing the standard would be fairly trivial.

Change [class] 9p4 to read:
    ...  The order of allocation of nonstatic data members
    separated by /different/ access-specifiers is unspecified. ...

Change [class.access.spec] 11.1p2 to read:
    The order of allocation of data members with /different/
    access-specifier labels is unspecified (9.2).

How does this suggestion sound?

-- David R. Tribble, dtribble@technologist.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: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1998/12/10
Raw View
On 9 Dec 1998 21:04:28 GMT, David R Tribble

>I can't think of a reason why this would unduly complicate
>compilers.  I also see no particular usefulness in considering
>them as structs with differently-ordered members.

Right.  But the way I would change the standard is this: the order of
data members is completely unspecified (even if they all fall within
the same access specifier).  This is because layout order is an
implementation detail, and if the optimizer can find a better layout
-- eg, one that results in faster access or less padding -- then
let it do so.  And furthermore, padding at the left should be
allowed too.  I guess the current rule about padding on left and
order of data members is for backward compatibility with C, right?


--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ 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: 1998/12/10
Raw View
In article <3.0.5.32.19981209142157.009758f0@central.beasys.com>, David
R Tribble <david.tribble@dallas.beasys.com> writes
>I can't think of a reason why this would unduly complicate
>compilers.  I also see no particular usefulness in considering
>them as structs with differently-ordered members.

And I disagree.  The utility may be small but why make it different from
the general rule?  The advantage of the current rule is that it allows
the programmer to free the compiler to optimise layout.  If I do not
want to allow that I just keep all my data members in one place.


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: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/12/10
Raw View
In article <3.0.5.32.19981209142157.009758f0@central.beasys.com>,
David R Tribble  <david.tribble@dallas.beasys.com> wrote:
>
>I think it would be reasonable to allow structs containing members
>having identical access-specifiers to be equivalent regardless of
>the number or placement of the access-specifiers.  For example, all
>of these should, in my mind, be considered equivalent:
>
>    struct S1
>    {
>        int  a;
>        int  b;
>        int  c;
>    };
>
>    struct S2
>    {
>        int  a;
>    public:
>        int  b;
>        int  c;
>    };
>
>    struct S3
>    {
>    public:
>        int  a;
>    public:
>        int  b;
>    public:
>        int  c;
>    };
>
>I can't think of a reason why this would unduly complicate
>compilers.=20

If you look back at the start of this thread you will see that
currently the standard requires that they are layout-compatible
(because they are POD-structs etc.)

> I also see no particular usefulness in considering
>them as structs with differently-ordered members.

Not in this case, but if we have:

struct S3 {
 public: char a;
 public: int b;
 public: char c;
};

it might be preferable to rearrange the members to squeeze
down the size of the struct (assuming that int has more restrictive
alignment than char), as if S3 were not a POD-struct.

This would require a minor modification of the standard and give
implementors somewhat more freedom (i.e. it would allow compilers
to do more tricks). It will be marginally easier for compilers
because they can use the same rearrangements regardless of whether
it is a POD-struct or not.

Currently most (all?) compiler ignore this possibility even in
the cases when they are allowed to rearrange them.

>Changing the standard would be fairly trivial.
>
>Change [class] 9p4 to read:
>    ...  The order of allocation of nonstatic data members
>    separated by /different/ access-specifiers is unspecified. ...

Separating the data-members only requires one access-specifier=20
and _different_ does thus not make sense.

In CD2 it was (9=A712)

The order  of  allocation  of nonstatic data members separated by=20
an access-specifier is unspecified.

I don't know if it you misquoted it or it was changed to say that
the order is also unspecified if they are separated by more than one
access-specifier!

>Change [class.access.spec] 11.1p2 to read:
>    The order of allocation of data members with /different/
>    access-specifier labels is unspecified (9.2).
>
>How does this suggestion sound?

I don't like it because layout-compatible structs restricts the compiler,
and is only useful in some strange hacks that C++ inherited from C.
Requiring extra precaution (i.e. no intervening access-specifiers)
in those cases does not seem excessive to me.

--
// Home page  http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]




[ 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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/12/10
Raw View
David R Tribble wrote:
>
> I think it would be reasonable to allow structs containing members
> having identical access-specifiers to be equivalent regardless of
> the number or placement of the access-specifiers.  For example, all
> of these should, in my mind, be considered equivalent:
>
>     struct S1
>     {
>         int  a;
>         int  b;
>         int  c;
>     };
>
>     struct S2
>     {
>         int  a;
>     public:
>         int  b;
>         int  c;
>     };
>
>     struct S3
>     {
>     public:
>         int  a;
>     public:
>         int  b;
>     public:
>         int  c;
>     };
>
> I can't think of a reason why this would unduly complicate
> compilers.  I also see no particular usefulness in considering
> them as structs with differently-ordered members.
>

If all members are ints, I don't see a point in it as well.
However, consider:

struct A1
{
  A1() {}  // make it non-POD
  char c;  // sizeof(c)==1==alignof(c)
  int i;   // sizeof(i)==4==alignof(i)
  char d;  // sizeof(d)==1==alignof(d)
};         // c___iiiid___ (since ascending order is guaranteed)

struct A2
{
  A2() {} // non-POD
  char c;
  int i;
public:
  char d;
};        // cd__iiii (since d needn't come after i)

Now, sizeof(A1)==12, while sizeof(A2)==8.

> Changing the standard would be fairly trivial.
>
> Change [class] 9p4 to read:
>     ...  The order of allocation of nonstatic data members
>     separated by /different/ access-specifiers is unspecified. ...
>
> Change [class.access.spec] 11.1p2 to read:
>     The order of allocation of data members with /different/
>     access-specifier labels is unspecified (9.2).
>
> How does this suggestion sound?

I don't like it.

BTW, aren't your structs equivalent anyway by the current rules,
due to being PODs and the requirements concerning unions?


[ 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: AllanW@my-dejanews.com
Date: 1998/12/01
Raw View
In article <36633D59.47DF@noSPAM.central.beasys.com>,
  dtribble@technologist.com wrote:
>
> jim.hyslop@leitch.com writes:
> > It seems to me the POD rule should take precedence, since the extra
> > access declarations (in the class B shown) are, in effect, redundant.
>
> Francis Glassborow wrote:
> > Au contraire.  By providing explicit access specifiers you can empower
> > the compiler to optimise layout.  I would go for refining the
> > definition of a POD by explicitly prohibiting any access specifiers
> > other than as the first statement. So:
> >
> >     struct A {
> >     public:        // redundant without influence
> >         int i;
> >         char a[3];
> >         int j;
> >         char b;
> >     };
> >
> > OK, its a POD but:
> >
> >     struct B {
> >         int i;
> >         char a[3];
> >     public:
> >         int j;
> >     public:
> >         char b;
> >     };
> >
> > Is NOT a POD and b can be place immediately after a[2] and reduce the
> > need for alignment padding.
>
> Eesh.  It isn't immediately clear that struct B is not a POD type.

Good point.

> [class] 9p4 states:
>     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.
>
> [dcl.init.aggr] 8.5.1p1 states:
>     An 'aggregate' is an array or a class (clause 9) with no user-
>     declared constructors (12.1), no private or protected non-static
>     data members (clause 11), no base classes (clause 10), and no
>     virtual functions (10.3).
>
> These would seem to imply that struct B is a POD type.

More than imply. I think it's very clear that B *IS* a POD type.

> However, [class.mem] 9.2p12 states:
>     ...  The order of allocation of nonstatic data members separated
>     by an access-specifier is unspecified (11.1).  ...
>
> [class.access.spec] 11.1p2 states:
>     The order of allocation of data members with separate access-
>     specifier labels is unspecified (9.2).
>
> These would seem to imply that struct B is not a POD type, even
> though all of its nonstatic data members are public.

It doesn't say that B is or isn't a POD type. It says something about
the order of data members.

> What is the rationale of not allowing struct B to be a POD type?

I think that it's clear: the compiler is allowed to rearrange the
data elements in B (something we traditionally associate only with
non-POD types), but in all other respects B is a POD type.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ 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: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/12/01
Raw View
jim.hyslop@leitch.com writes:
> It seems to me the POD rule should take precedence, since the extra
> access declarations (in the class B shown) are, in effect, redundant.

Francis Glassborow wrote:
> Au contraire.  By providing explicit access specifiers you can empower
> the compiler to optimise layout.  I would go for refining the
> definition of a POD by explicitly prohibiting any access specifiers
> other than as the first statement. So:
>
>     struct A {
>     public:        // redundant without influence
>         int i;
>         char a[3];
>         int j;
>         char b;
>     };
>
> OK, its a POD but:
>
>     struct B {
>         int i;
>         char a[3];
>     public:
>         int j;
>     public:
>         char b;
>     };
>
> Is NOT a POD and b can be place immediately after a[2] and reduce the
> need for alignment padding.

Eesh.  It isn't immediately clear that struct B is not a POD type.

[class] 9p4 states:
    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.

[dcl.init.aggr] 8.5.1p1 states:
    An 'aggregate' is an array or a class (clause 9) with no user-
    declared constructors (12.1), no private or protected non-static
    data members (clause 11), no base classes (clause 10), and no
    virtual functions (10.3).

These would seem to imply that struct B is a POD type.

However, [class.mem] 9.2p12 states:
    ...  The order of allocation of nonstatic data members separated
    by an access-specifier is unspecified (11.1).  ...

[class.access.spec] 11.1p2 states:
    The order of allocation of data members with separate access-
    specifier labels is unspecified (9.2).

These would seem to imply that struct B is not a POD type, even
though all of its nonstatic data members are public.

Personally, I can't see why struct B shouldn't be a POD type.
After all, all of its members have public access.  Perhaps 9.2p12
and 11.1p2 were meant to be:
    The order of allocation of nonstatic data members separated
    by a /different/ access-specifier is unspecified.
and:
    The order of allocation of data members with /different/ access-
    specifier labels is unspecified.
instead?

(It seems to me that compilers would have to keep extra information
about the struct members in order to treat struct B as a non-POD
type.  The simple approach in deciding whether a struct is a POD or
not is to check that all its data members are public; the 11.1 rule
seems to require a more complicated check, whereby the presence of
multiple 'public' specifiers within a struct declaration is
remembered.)

What is the rationale of not allowing struct B to be a POD type?

-- David R. Tribble, dtribble@technologist.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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/12/01
Raw View
David R Tribble wrote:
>
> jim.hyslop@leitch.com writes:
> > It seems to me the POD rule should take precedence, since the extra
> > access declarations (in the class B shown) are, in effect, redundant.
>
> Francis Glassborow wrote:
> > Au contraire.  By providing explicit access specifiers you can empower
> > the compiler to optimise layout.  I would go for refining the
> > definition of a POD by explicitly prohibiting any access specifiers
> > other than as the first statement. So:
> >
> >     struct A {
> >     public:        // redundant without influence
> >         int i;
> >         char a[3];
> >         int j;
> >         char b;
> >     };
> >
> > OK, its a POD but:
> >
> >     struct B {
> >         int i;
> >         char a[3];
> >     public:
> >         int j;
> >     public:
> >         char b;
> >     };
> >
> > Is NOT a POD and b can be place immediately after a[2] and reduce the
> > need for alignment padding.
>
> Eesh.  It isn't immediately clear that struct B is not a POD type.

[...]

> These would seem to imply that struct B is a POD type.

According to the real, existing standard: Yes.
According to what Francis Glassborrow would like: No.

[...]

> What is the rationale of not allowing struct B to be a POD type?

Optimisation.

If B is considered a POD, the layout must be (assuming 4 byte aligned
4 byte int; _ denotes padding):

iiiiaaa_jjjjb___

Therefore sizeof(B)==16, while
sizeof(B::i)+sizeof(B::a)+sizeof(B::j)+sizeof(B::b)==12.

If B were not a POD, the layout could be:

iiiiaaabjjjj

Therefore sizeof(B)==12, no padding needed.

The problem is that POD is just a couple of independant guarantees:

- Order of members in declaration matches order of members in memory

  This could IMHO be removed, since usually POD structs have no
  intermediate access specifyers at all, and without intermediate
  access specifiers, the memory order is defined anyway.
  Also AFAIK all class definitions must agree token-wise;
  this automatically includes redundant access specifiers.
  Therefore I doubt that many (if any) programs would fail if this
  special POD rule were dropped completely.

- Objects may be copied with memcpy.

  Here the POD definition is too strict, since it wouldn't hurt
  to have non-trivial non-copy constructors or non-virtual POD base
  classes.

- Objects may be put in unions

  In this case, it is debatable if the current POD definition is the
  best fit. It's at least reasonable for that purpose.

Of course, separating the last two issues would have complicated
the standard; it is debatable if this would have been worth it.
However, dropping the first POD rule would even have simplified
things. And less exceptions are IMHO always a good idea.

Note that today you can allow this optimisation quite easily:

class C
{
public:
  C() {}
  int i;
  char a[3];
  int j;
  char b;
};

The default constructor (despite making no difference to the compiler
generated default constructor) makes that class a non-POD, and
therefore allows the compiler optimizing it.

OTOH I don't know a compiler which makes that optimisation today.


[ 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: 1998/12/01
Raw View
In article <36633D59.47DF@noSPAM.central.beasys.com>, David R Tribble
<david.tribble@noSPAM.central.beasys.com> writes
>What is the rationale of not allowing struct B to be a POD type?

I am quite happy for it to be so and the change I would make to the
rules would simply be that it is not layout compatible with any other
POD of a different name  (which is the only problem that I can see)

Perhaps we should raise a deffect report as the standard seems to be
contradictory.



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: jim.hyslop@leitch.com
Date: 1998/11/25
Raw View
In article <5az76TAckpV2EwfJ@robinton.demon.co.uk>,
  Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
> In article <734nqq$brd$1@nnrp1.dejanews.com>, jim.hyslop@leitch.com
> writes
> >It seems to me the POD rule should take precedence, since the extra access
> >declarations (in the class B shown) are, in effect, redundant.
>
> Au contraire.  By providing explicit access specifiers you can empower
> the compiler to optimise layout.  I would go for refining the definition
> of a POD by explicitly prohibiting any access specifiers other than as
> the first statement. So:
>
> struct A {
> public:        // redundant without influence
>         int i;
>         char a[3];
>         int j;
>         char b;
> };
>
> OK, its a POD but:
>
> struct B {
>    int i;
>    char a[3];
> public:
>    int j;
> public:
>    char b;
> };
>
> Is NOT a POD and b can be place immediately after a[2] and reduce the
> need for alignment padding.

I would agree with that redefinition, but the question is how will
implementations interpret the existing rules (as I understand it, the
Standard cannot be changed for five years)?  OTOH, how many implementations
actually do re-arrange the data members?  I guess to be on the safe side, if
you want to guarantee your class is treated as a PODS, avoid more than one
access specifier.

--
Jim

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ 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: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/24
Raw View
In article <5az76TAckpV2EwfJ@robinton.demon.co.uk>,
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
>In article <734nqq$brd$1@nnrp1.dejanews.com>, jim.hyslop@leitch.com
>writes
>>It seems to me the POD rule should take precedence, since the extra access
>>declarations (in the class B shown) are, in effect, redundant.
>
>Au contraire.  By providing explicit access specifiers you can empower
>the compiler to optimise layout.  I would go for refining the definition
>of a POD by explicitly prohibiting any access specifiers other than as
>the first statement.

I though about this use before posting the original question,
but I think it would be better to specify that extra access-specifier
makes it a POD where the order of the data members is implementation-defined.

Only the paragraphs about layout-compatible types and pointer to
first member of the struct needs to be changed.

The reason for making them PODs with unknown order is that some
uses of POD don't care about the order, e.g. copying the entire
POD-struct by memcpy, and could also benefit from optimized storage.

Furthermore there might be access-specifiers for functions or
static data members in a POD, and I see no need to forbid these
in POD-types. (An alternative would to require all non-static data members
in a POD to be given without intervening access-specifiers).

--
// Home page  http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]



[ 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: 1998/11/25
Raw View
In article <73ecaq$j2m$1@news.lth.se>, Email_To <?.Olsson@dna.lth.se>
writes
>I though about this use before posting the original question,
>but I think it would be better to specify that extra access-specifier
>makes it a POD where the order of the data members is implementation-defined.

In other words a POD that is not guaranteed to be layout compatible with
anything other than itself.  Yes I could go along with that.

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: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/24
Raw View
In article <734nqq$brd$1@nnrp1.dejanews.com>, jim.hyslop@leitch.com
writes
>It seems to me the POD rule should take precedence, since the extra access
>declarations (in the class B shown) are, in effect, redundant.

Au contraire.  By providing explicit access specifiers you can empower
the compiler to optimise layout.  I would go for refining the definition
of a POD by explicitly prohibiting any access specifiers other than as
the first statement. So:

struct A {
public:        // redundant without influence
        int i;
        char a[3];
        int j;
        char b;
};

OK, its a POD but:

struct B {
   int i;
   char a[3];
public:
   int j;
public:
   char b;
};


Is NOT a POD and b can be place immediately after a[2] and reduce the
need for alignment padding.


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: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/20
Raw View
The recent thread, 'Reposting "Exposing private/protected members"'
made me wonder about the following:

class B {
 public:
  T x;
 private:
 public:
  int i;
};
B b;

Does the standard allow 'b.i' to be placed before 'b.x' in memory?

CD2 seems to allow it:
9.2/12 'The order  of  allocation  of  nonstatic data members separated
by an access-specifier is unspecified.'
11.1/2 'The order of allocation of data members with separate access-specifier
  labels is unspecified.'

But if T is a POD-type B is layout-compatabile(9.2/14) to the following class
where 'a.x' must be before 'a.i':

class A {
 public:
  T x;
  int i;
};
A a;

(Note: B is a POD-type because it does not contain non-static
private data-members).

Was this changed in the standard or am I missing something?

--
// Home page  http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
---
[ 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: jim.hyslop@leitch.com
Date: 1998/11/21
Raw View
In article <7315cd$f5$1@news.lth.se>,
  Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson) wrote:
> The recent thread, 'Reposting "Exposing private/protected members"'
> made me wonder about the following:
>
> class B {
>  public:
>   T x;
>  private:
>  public:
>   int i;
> };
> B b;
>
> Does the standard allow 'b.i' to be placed before 'b.x' in memory?
>
> CD2 seems to allow it:
> 9.2/12 'The order  of  allocation  of  nonstatic data members separated
> by an access-specifier is unspecified.'
> 11.1/2 'The order of allocation of data members with separate access-specifier
>   labels is unspecified.'
>
> But if T is a POD-type B is layout-compatabile(9.2/14) to the following class
> where 'a.x' must be before 'a.i':
>
> class A {
>  public:
>   T x;
>   int i;
> };
> A a;
>
> (Note: B is a POD-type because it does not contain non-static
> private data-members).
>
> Was this changed in the standard or am I missing something?
Nope, it's the same in the final standard.

Boy, some people just love to think of ways to test rules, don't they ;-)

Seems to me like you just found a loophole in the Standard - B is a POD type,
which must be layout-compatible with A, but B has members separated by access
specifiers (you could even eliminate the private: and 9.2 would still apply)
which means the compiler is not required to place them in a particular order.

It seems to me the POD rule should take precedence, since the extra access
declarations (in the class B shown) are, in effect, redundant.

--
Jim

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ 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              ]