When S is a trivial subclass of T, is it safe to use an array of S where an array of T is expected?

后端 未结 5 407
甜味超标
甜味超标 2021-01-11 15:19

Consider the following declarations of a pair of related structs. The descendant class adds no member variables, and the only member function is a constructor that does noth

5条回答
  •  鱼传尺愫
    2021-01-11 15:49

    Is behavior of this program defined? Does the answer depend on the body of foo, like whether it writes to the array or only reads from it?

    I'm gonna hazard an answer saying that the program is well defined (as long as foo is) even if it is written in another language (e.g. C).

    If sizeof(Derived) is unequal to sizeof(Base), then behavior is undefined according to the answers to a previous question about a base pointer to an array of derived objects. Is there any chance the objects in this question will have differing sizes, though?

    I don't think so. According to my reading of the standard(*) §9.2 clause 17

    Two standard-layout struct (Clause 9) types are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in declaration order) have layout-compatible types (3.9).

    §9 clauses 7 through 9 detail the requirements for layout-compability:

    7 A standard-layout class is a class that:

    • has no non-static data members of type non-standard-layout class (or array of such types) or reference,

    • has no virtual functions (10.3) and no virtual base classes (10.1),

    • has the same access control (Clause 11) for all non-static data members,

    • has no non-standard-layout base classes,

    • either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and

    • has no base classes of the same type as the first non-static data member.

    8 A standard-layout struct is a standard-layout class defined with the class-key struct or the class-key class. A standard-layout union is a standard-layout class defined with the class-key union.

    9 [ Note: Standard-layout classes are useful for communicating with code written in other programming languages. Their layout is specified in 9.2. — end note ]

    Note especially the last clause (combined with §3.9) - according to my reading this is guaranteeing that as long as you're not adding too much "C++ stuff" (virtual functions etc. and thus violating the standard-layout requirement) your structs/classes will behave as C structs with added syntactical sugar.

    Would anyone have doubted the legality if Base didn't have a constructor? I don't think so as that pattern (deriving from a C structure adding a constructor/helper functions) is idiomatic.

    I'm open to the possibility that I'm wrong and welcome additions/corrections.

    (*) I'm actually looking at N3290 here, but the actual standard should be close enough.

提交回复
热议问题