5 ms·
> In other words, C structs and C++ structs are not the same thing (although C++ can usually handle C structs too). C structs are Plain Old Data. C++ structs ar
by chipdart 2y ago
> In other words, C structs and C++ structs are not the same thing (although C++ can usually handle C structs too). C structs are Plain Old Data. C++ structs are "objects" and there are pages and pages of rules in the C++ Standard about what that means, and there's no way the C Standard can incorporate all that.
I think this glances over what structs actually are in C++, and unwittingly portrays them as something different.
Structs in C++ are definitely exact like structs in C. Or they can be, if that's what you're aiming for. If you include a C header file that defines a struct in a C++ program, you build it, and you use instances of that struct to pass them to C programs, everthing just works.
The detail you need to be mindful of is that C structs support a subset of all the features supported by C++ classes, and once you start to use those features C++ also allows implementations to forego some constraints.
If you expect to use a struct in C++ but still define it in a way that you make it include features that are not supported in C then you can't pin that on the language.
https://learn.microsoft.com/en-us/cpp/cpp/trivial-standard-layout-and-pod-types https://learn.microsoft.com/en-us/cpp/cpp/trivial-standard-l...
Using C-like structs is a very common use case, to the point that the standard explicitly defines the concept of standard layout and builds upon that to specify the concept of a standard layout type. A struct/class that is a standard layout type, which means it's a POD type, corresponds exactly with C structs. They are explicitly defined in terms of retaining interoperability with other languages.
- schmidt_fifty 2y agoThe detail missing from this explanation is that structs and classes are the same thing with different default visibility. I found this enormously confusing when learning the language, and I think it was a major mistake. My assumption was that a struct was exactly the same as a c struct, and the "new" functionality was all a part of the classes. Still. There's always extern "c".
- rramadass 2y agoExactly. This is one of the basic things (i.e. PODs) you learn in C++ that i am surprised the gp didn't know of it. I myself have written systems with C-structs/C-api and wrapped the same C-structs (by deriving) in C++ classes (being careful with any introduced vptr/vtable) to happily provide/extend C-code/libraries via C++ apis.
- gary_0 2y agoOf course I know about the POD idiom. You and chipdart are misunderstanding me because there's a tension between how the C++ Standard defines things and how C++ gets used in real life. Because strictly speaking, the Standard doesn't really have a concept of POD[0]. What it does have is "trivial" classes and the concept of object lifetime. For instance, if your class/struct isn't trivially_copyable and you memcpy it like a C struct, you're in Undefined Behavior country. If your class/struct is such that you must observe C++'s lifetime rules, but you are writing its fields by casting a char pointer to some bytes, that's UB. But yes, if you make extra sure (under threat of footgun) that your struct only has simple types in it and doesn't use virtual or define any ctors/dtors or use protected/private or use inheritance and all of its members follow those rules etc etc, maybe you can treat it like a C struct. But the C++ Standard is telling a different story. Keep in mind, I'm not blaming you for ignoring all these complications if at the end of the day the compiler seems to give you the behavior you expect. But the fun of C++ is that it's kind of two programming languages in one: the language the Standard defines, and the language the typical programmer thinks it is. [0] There was std::is_pod, but it was deprecated because it doesn't reflect how the Standard actually defines things. A bit of a cruel joke, dangling that in front of us and then yanking it away.
- rramadass 2y agoPOD is not an idiom. It was an actual specification (in a sense) for interop between C++ and C. Only in the later standards (maybe starting at C++14?) did the committee refine it further as "POD = Trivial + Standard_Layout" but that is just a redefinition without any fundamental change in semantics. So you can happily write C++ code with just your understanding of POD from C++98 in practice and everything will work fine. References: 1) Trivial, standard-layout, POD, and literal types - https://learn.microsoft.com/en-us/cpp/cpp/trivial-standard-layout-and-pod-types?view=msvc-170 https://learn.microsoft.com/en-us/cpp/cpp/trivial-standard-l... 2) No more plain old data - https://mariusbancila.ro/blog/2020/08/10/no-more-plain-old-data/ https://mariusbancila.ro/blog/2020/08/10/no-more-plain-old-d...
- gary_0 2y ago
- rkangel 2y ago> Using C-like structs is a very common use case Not true. Using C structs themselves in C++ is very common - when you include the C header file, the relevant declarations are wrapped in "extern "C" {}" which gives structs C semantics. You can do this because C++ is backwards compatible with C. Most of the time when you use a struct in C++ you're just ignoring most of the capabilities of objects (which is fine!). If you declare a struct in C++, you're getting an object. The only difference between the struct and class keywords in C++ is the default privacy of the members.
- gpderetta 2y agoA C++ structure has exactly the equivalent semantics of a C structure if it exists. Extern "C" only affects linkage of functions. It has no effect on structure definitions.
- OskarS 2y agoIt absolutely does not. A C++ structure is a much richer object: it can have custom copying, moving and assignment behaviours, it can have vtables, it has RAII, etc. That's the whole point about the "object model" in the article: C++ has it, C does not. What I think you're trying to say is "a POD structure with no custom behavior is essentially identical in C and C++". That is mostly true, though if the struct contains a union, C++ has stricter UB rules (there might be other differences as well, but that's the one I can think of at the moment).
- deleted 2y ago[deleted]
- gpderetta 2y agoWhat I'm saying is that extern "C" has no effect on structure compatibility.
- deleted 2y ago[deleted]