0

This seems to work on my compiler but is it standard? Should I do a memcpy instead?

struct Foo { u32 a, b; u8 c[24]; }
class Bar {
    Foo f; 
public: 
    Bar(Foo&f):f(f){} 
};
  • 1
    yes it is standard to performing bit-wise copying – Bryan Chen Oct 31 '14 at 04:24
  • it is perfectly OK, as `Foo` is an agregate. A memcpy is implicitly performed. See http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special – vsoftco Oct 31 '14 at 04:25
  • @vsoftco: I heard of POD but never aggregate –  Oct 31 '14 at 04:34
  • @acidzombie24 Here is a link http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special Since you don't have any explicitly declared copy ctors, a bitwise-copy is performed, so you should be safe. – vsoftco Oct 31 '14 at 04:36
  • 1
    @vsoftco The implicit generation of a copy constructor does not require the type to be an aggregate, and even if it is, the compiler is almost certainly not going to emit an actual call to `memcpy` or even inline `memcpy` itself; it can generate more efficient code since the size is known at compile time. – Brian Bi Oct 31 '14 at 04:36
  • @Brian yes, but if the type is an aggregate (as it is in this case), then the default copy ctor is just a bit-wise copy. (modified my previous comment also). What I wanted to say is that in this case, the class is just an aggregate, so a default bit-wise copying ctor is generated, and everything should work just fine. Isn't this accurate? – vsoftco Oct 31 '14 at 04:39
  • 2
    @vsoftco I believe the term is *trivially copyable*. Aggregates are usually, but not always, trivially copyable. – user657267 Oct 31 '14 at 04:45
  • @user657267, it may be, somehow I am really unable to keep track of all the nuances/exceptions of C++, and in my opinion (although I still find C++ the best language) I find that all of these nuances/interpretations are just making everyone's life harder. I truly hope for a significant simplification in the next major standard, as I fell C++ is becoming a monster, harder and harder to tame. Even this question, it seemed simple, although it took a significant effort to find out the answer to it (and I'm still not convinced I got it right). – vsoftco Oct 31 '14 at 04:48
  • It's worth noting that structs behave the same way as classes, except that member visibility is public by default (versus private by default in a class). All of the same rules regarding copying, assignment, etc. all apply to structs and classes equally. – cdhowie Oct 31 '14 at 04:49
  • @vsoftco You're never going to get simplification out of a new standard. It is extremely rare for things to get removed from programming languages. The Cobol `ALTER` verb is almost the only exception I can think of. And even if you do get a removal, compiler vendors have to support all past versions anyway. – user207421 Oct 31 '14 at 04:53
  • @EJP, agree, I think the major problem is the fear of breaking legacy code. In my opinion, one has to take a step forward, and forget about legacy code and just implement a better language with a decent syntax. Right now, writing a C++ parser is almost as complicated as sending a space probe to Mars. If we'll always want backwards compatibility, then of course the new implementation will almost always be a superset, that include all previous defects. – vsoftco Oct 31 '14 at 04:56
  • 1
    @vsoftco I looked at the link. I know PODs are a bitwise copy and I know a memcpy will work. I just never heard of an 'aggregate' in C++ until now. The link makes it sound like all PODs are aggregates but aggregates might not be a POD? I didn't read the article linked in that link –  Oct 31 '14 at 04:56
  • @acidzombie24, the term "aggregate" seem to appear in `3.8` of the standard `3.8 Object lifetime [basic.life]`, without a previous definition. It is however defined in `8.5.1 Aggregates [dcl.init.aggr]`. This is according to my latest sync with the std, `N4140` from github. – vsoftco Oct 31 '14 at 05:23
  • @vsoftco An aggregate need not be a POD. An aggregate can be a struct with, say, an `std::string` and an `std::vector`. So, a plain bitwise copy or `memcpy` would of course not do. – juanchopanza Oct 31 '14 at 06:39
  • @juanchopanza you're right, in that case the copy ctor of the member will take care of the copying and of course memcpy wouldn't work. I actually didn't know until now that an aggregate may contain members with a user defined constructor, thanks for pointing it out. – vsoftco Oct 31 '14 at 12:01

1 Answers1

1

In C++11 International Standard, struct Foo is regarded as POD (Plain Old Data, refer to clause 9 spec#10), and it is trivially copyable type(refer to clause 3.9 spec#9).

the bitwise-copying is normally determined by the size of the the type, for small types, it may be optimized as a simple movl/movq instruction. The compiler will do the job, thus you do not need memcpy in the constructor block of class Bar, since you have set the value in the initializer list Bar(Foo&f):f(f).

Peixu Zhu
  • 2,111
  • 1
  • 15
  • 13