3

I came across this question recently. My goal is to understand how the C++ compiler views struct definitions which hold standard library containers such as std::vector.

Ben Voigt's answer to the linked question cites the following from the C++0x standard:

....

A trivial class is a class that has a trivial default constructor (12.1) and is trivially copyable.

[ Note: In particular, a trivially copyable or trivial class does not have virtual functions or virtual base classes. — end note ]

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,

....

I'm almost certain that the bolded text implies that the following is undefined behavior

struct A 
{
    std::vector< SomeType > myVec;
    int myC;  
    A( int c ) : myC : (c) {}
};

int main( void )
{
    A one( 1 );
    A two( 2 );

    SomeType k, z;
    one.myVec.push_back( k );
    two.myVec.push_back( z );

    memcpy( &two, &one, sizeof( A ) ); // bad juju
}

And the same would be the case for any type which is from the standard library, including simpler types such as std::string. This would be due to the nature of the library's design, given its large usage of inheritance and template programming.

So, while struct A would resemble that of a POD type, the fact that it contains that standard library type automatically invalidates it from that category, as far as the compiler is concerned.

Are my assumptions correct?

Community
  • 1
  • 1
zeboidlund
  • 9,731
  • 31
  • 118
  • 180
  • 2
    No, `A` is not trivially copyable. And neither `std::vector` nor `std::string` is something I would call "simple". A select few standard library classes are guaranteed to be trivially copyable. – T.C. Nov 27 '14 at 07:55
  • 5
    Standard layout and PODness aren't relevant to what you're asking about; `A` isn't trivially copyable, and _that_ is the requirement that matters. – ildjarn Nov 27 '14 at 08:01
  • 2
    Not only is it not a POD "as far as the compiler is concerned", but it isn't as far as the *standard* is concerned; its members are not all trivially copyable. It has nothing to do with layout, inheritance, templates, or being "simple". – molbdnilo Nov 27 '14 at 08:21
  • 2
    "STL library" generally is a harmless label, but here it is quite misleading. The STL was integrated into the Standard Library about 2 decades ago, but `std::string` for instance came from somewhere else. – MSalters Nov 27 '14 at 08:39
  • @MSalters Even more so with "STL library". Since that sounds like it's a disambiguation to mean the "STL" and not the "standard library" (as the acronym would be redundant otherwise.) –  Nov 27 '14 at 09:24
  • `My goal is to understand how the C++ compiler views struct definitions` This sentence doesn't make much sense to me. Obviously compilers interpret the standard differently and are subject to bugs. Similarly with `as far as the compiler is concerned.` If you want an answer that addresses the standard (and not a specific implementation), why are you bringing the compiler into this? Furthermore, the C++ standard library, a compiler and standard library implementations are three different things. I think your question needs to be reworded. –  Nov 27 '14 at 09:28

1 Answers1

3

No. Your basic assumptions are flawed. "Standard layout" is not related to templates. E.g. std::pair<T1, T2> has standard layout if and only if both T1 and T2 do. Same goes for std::array<T,N>

However, none of the Containers have standard layout. The whole point of their allocators is to have advanced memory management.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • 1
    They may or may not be standard layout. They are definitely not trivially copyable. – T.C. Nov 28 '14 at 07:33
  • @T.C. `std::array` is though and `static_assert(std::is_pod>())` passes on GCC 6.4, see also: https://stackoverflow.com/questions/3674247/is-stdarrayt-s-guaranteed-to-be-pod-if-t-is-pod – Ciro Santilli OurBigBook.com Oct 26 '18 at 10:53