take two following classes:

class Test1{
     public:
      Test1()=default;
      Test1(char in1,char in2):char1(in1),char2(in2){}
      char char1;
      char char2;
    };
    class Test2{
     public:
      Test2()=default;
      Test2(char in1,char in2):char1(in1),char2(in2){}
     private:
      char char1;
      char char2;
    };

I know in c++0x both of these classes are considered as POD types and we can initialize objects of them using initializer lists as below:

Test1 obj1={'a','b'};//valid in c++0x
    Test2 obj2={'a','b'};//valid in c++0x

But I wonder what the technical reason is that when we have different access specifiers in a class like below, it's not possible to use initializer list for initializing objects of that class and that class is not considered as a POD type ?

class Test{
     public:
      Test()=default;
      Test(char in1,char in2):char1(in1),char2(in2){}
      char char1;
     private:
      char char2;
    };
    Test obj={'a','b'};//invalid in c++0x

In case you don't know definition of PODs in c++0x:
A class/struct is considered a POD if it is trivial, standard-layout, and if all of its non-static members are PODs.

A trivial class or struct is defined as one that:

1. Has a trivial default constructor. This may use the default constructor syntax (SomeConstructor() = default; ).
2. Has a trivial copy constructor, which may use the default syntax.
3. Has a trivial copy assignment operator, which may use the default syntax.
4. Has a trivial destructor, which must not be virtual.

A standard-layout class or struct is defined as one that:

1. Has only non-static data members that are of standard-layout type
2. Has the same access control (public, private, protected) for all non-static members
3. Has no virtual functions
4. Has no virtual base classes
5. Has only base classes that are of standard-layout type
6. Has no base classes of the same type as the first defined non-static member
7. Either has no base classes with non-static members, or has no non-static data members in the most derived class and at most one base class with non-static members. In essence, there may be only one class in this class's hierarchy that has non-static members.

In case you don't know what a trivial constructor or operator is:
Compiler generates a trivial one of each of following items for a class, in case it isn't user-declared:
Copy constructor, destructor and copy assignment operator.
And also if there's no user-declared constructor for a class, a trivial default constructor is generated for that class, in case there are any user-declared constructors you can use the syntax(SomeConstructor() = default; ) to make your own trivial default constructor.

Edited 6 Years Ago by Garrett2011: n/a

I remember, as I was looking into making an ABI for my projects, that there is very loose standards about how a compiler is allowed to lay out the variables of different scopes. From what I recall, public data members are required to be ordered in memory as they are declared in the class definition, but private members are not, the compiler can choose to arrange them differently. That is in fact one of the major reasons why the Pimpl or Cheeshire-Cat Idiom is often called a "compiler firewall", because it makes the private section have only one data member, i.e. the pimpl pointer, and thus, all compilers will produce the same binary foot-print for an object of that class (given that other conditions are satisfied too!).

So it appears that in the new up-coming standard they may have added some guidelines to make it possible to have all-private data members in a POD. But still not to break code that has mixed public-private data whose binary foot-print is compiler-specific (and even compiling options specific), it has to remain non-POD.

I'm not sure this all makes sense, or is really true, but this is my impression of it.

Edited 6 Years Ago by mike_2000_17: n/a

mike_2000_17

That is in fact one of the major reasons why the Pimpl or Cheeshire-Cat Idiom is often called a "compiler firewall", because it makes the private section have only one data member, i.e. the pimpl pointer, and thus, all compilers will produce the same binary foot-print for an object of that class (given that other conditions are satisfied too!).

I didn't get that, can you explain this a little more clarified ?
As a matter of fact I was aware of that order-of-members-in-memory idiom, but still the thing that doesn't make sense to me is that despite the fact that the order is not specified from a programmer point of view in the case there are more than one access specifier in a class, compiler should still be able to accept initializer list cause it knows that order.

>> compiler should still be able to accept initializer list cause it knows that order.
I guess vijayan was able to answer that, so I guess the new standard will allow that without problems.

I think it all revolves around the problem for compilers to achieve multiple inheritance (especially virtual inheritance) where the vtable pointer and data have to be mixed to some degree, and so the compiler has to have some freedom in choosing how to order private, protected and public data members. But I would really be going beyond my expertise if I said anything more. You should browse around the web on issues related to "Binary Compatibility in C++" to get a good understanding of this. I did that a while ago and it was very helpful, but it is also quite a bit complex and I don't remember enough of it to explain this more myself. Sorry.

mike_2000_17

>> compiler should still be able to accept initializer list cause it knows that order.
I guess vijayan was able to answer that, so I guess the new standard will allow that without problems.

I think it all revolves around the problem for compilers to achieve multiple inheritance (especially virtual inheritance) where the vtable pointer and data have to be mixed to some degree, and so the compiler has to have some freedom in choosing how to order private, protected and public data members. But I would really be going beyond my expertise if I said anything more. You should browse around the web on issues related to "Binary Compatibility in C++" to get a good understanding of this. I did that a while ago and it was very helpful, but it is also quite a bit complex and I don't remember enough of it to explain this more myself. Sorry.

Nice info you gave on this topic generally, why would you be sorry man.:)

Edited 6 Years Ago by Garrett2011: n/a

This question has already been answered. Start a new discussion instead.