Can it? I don't think we guarantee contiguous layout unless the class has
standard layout.
// Out of class definition I would write: std::size_t Container::offsets = {offsetof(z), offset(x), offset(y)};
// Obviously using 'static constexpr std::size_t offsets = {offsetof(z), offset(x), offset(y)};' in the class definition is better, but it's ill-formed as per current standard. See N3308 for details.
// Out of class definition I would write: std::size_t Container::offsets = {offsetof(z), offset(x), offset(y)};
// Obviously using 'static constexpr std::size_t offsets = {offsetof(z), offset(x), offset(y)};' in the class definition is better, but it's ill-formed as per current standard. See N3308 for details.
Why it is that you want this is more or less irrelevant. `offsetof` is currently a very simple macro. What you're wanting can't be a simple macro, because it needs to do very different things for non-standard-layout types. It would have to be a language feature (since you can't pass types to functions and identifiers to functions).
At which point, you're now talking about something very close to compile-time reflection and iteration over members of a class. Which is best handled by providing actual compile-time reflection, rather than a mere `offsetof` macro.
Is the way to determine its member offsets should be different with the way for a standard-layout class?
Encapsulation or accessibility is not the key point. Using accessors here would likely bloat the framework code a lot and make it far less flexible.
It should be noted that the place for discussing proposals (which this is, since it isn't in the standard) is elsewhere.
That being said, the standard-layout/trivial rules follow existing practice. Many compilers didn't have to change much to support them (outside of the machinery needed to provide is_standard_layout and so forth). The change you're proposing would be an actual change to compilers and how they lay out objects in memory.
If accessibility was not a key point, then why do you need to make some of the members public and some not? And I've never seen encapsulation or accessors make something less flexible; I'm curious as to how that would work.
It should be noted that the place for discussing proposals (which this is, since it isn't in the standard) is elsewhere.
That being said, the standard-layout/trivial rules follow existing practice. Many compilers didn't have to change much to support them (outside of the machinery needed to provide is_standard_layout and so forth). The change you're proposing would be an actual change to compilers and how they lay out objects in memory.
I know the place for discussing proposals. But it isn't a proposal, but just an idea. I can't work out a proposal now, because I am not 100% sure it's feasible, as you said, to make them "follow existing practice".
Perhaps you misunderstood my idea. I strongly suspect there is some work can be done conceptually, like changing POD to standard-layout/trivial, with almost no actual change to compilers. The only things to implement should be: a) adding an interface(something like std::is_standard_layout) to check if a type is fit for the proposed category; b) changing implementation of offsetof if necessary, and confirm there are no redundant diagnostic messages. I'm glad to see how compilers have to make actual change of object layout.
If accessibility was not a key point, then why do you need to make some of the members public and some not? And I've never seen encapsulation or accessors make something less flexible; I'm curious as to how that would work.
Here different access control of data members are used to show the enclosing class is not standard-layout. Even if all the members are standard-layout types, no base or virtual member function exists, it is still the problem. The example is more closed to the actual code to illustrate the original problem and to try getting some other ways unrelated to object layout can solve it.
Excessive encapsulating doesn't make sense. It exposes no extra functionality but often force the client code to be cumbersome. Same amount of code using excessive encapsulated interface would do less work than proper one. If there are both simple public getter and setter for a data member, and no need to work with source code tools depend on accessors, I'd rather like make the data member itself to be public, not to add accessors. (Though I do use accessors if necessary.)
And here accessors don't help at all: I need to get/access/traverse children via a virtual function in the abstract base class, but different derived classes can hold different children and accessors.
Excessive encapsulating doesn't make sense. It exposes no extra functionality but often force the client code to be cumbersome. Same amount of code using excessive encapsulated interface would do less work than proper one. If there are both simple public getter and setter for a data member, and no need to work with source code tools depend on accessors, I'd rather like make the data member itself to be public, not to add accessors. (Though I do use accessors if necessary.)
This is more of a code style discussion, but this kind of coding runs into a problem the moment you want to *change* how data is stored. You modify the type of a member or split it into two members or whatever. That now means that you have to change everyone who uses it, with no real fall-back or backwards compatibility.
Religiously using accessors allows you to use the same interface but with different back-end data. This is a good 30% of the reason for why encapsulation is good. As to how "cumbersome" it makes the client, that is a matter of opinion.
It's also the place for working out ideas that would become proposals.
This place is for discussing the standard as it currently is. Like asking if an initializer list is a type.
I understand that you suspect that, but why do you suspect that? Do you have real knowledge of multiple compilers to know that this is true?
Base and Derived classes both having data members. This allows compilers the freedom to put the base class before the derived class, or to put the derived class before the base class. And I know for a fact that there are some compilers that do it one way and some that do it another. I've been involved in code that has to work with both while allowing for a form of serialization. You're not going to get the committee to force some compilers to put their base classes first or something.
Virtual member functions and/or virtual base classes. This allows compilers the freedom to implement virtual functions/bases as it sees fit. You're not going to get the committee to force compilers to adopt the vtable as the only way to do virtual dispatch, nor are you going to get them .
I focus on standard-layout because it's the only way that you can have a consistent enough layout scheme for offsetof to work. If you can't expand the defintion of standard-layout to cover these cases, then you're not going to be able to get an offsetof macro to work.
The most you might get the committee to go along with is allowing the access controls to be standard layout. And that's only a maybe.
This is more of a code style discussion, but this kind of coding runs into a problem the moment you want to *change* how data is stored. You modify the type of a member or split it into two members or whatever. That now means that you have to change everyone who uses it, with no real fall-back or backwards compatibility.
Religiously using accessors allows you to use the same interface but with different back-end data. This is a good 30% of the reason for why encapsulation is good. As to how "cumbersome" it makes the client, that is a matter of opinion.
You're not getting the committee to allow virtual classes to be standard-layout. The distinction was made specifically to allow compilers the freedom to do what they feel is best for derived classes and virtual dispatch.