1. 17

  2. 13

    The really interesting thing is that C++ does have a meaningful distinction between POD-types and non-POD-types (Plain Ordinary Data) which affects the semantics of the type quite a lot. But either “struct” or “class” can be used for POD or non-POD. It would have made sense to use struct for POD and class for non-POD but that’s not what the committee chose to do. Instead, you just have to memorize the rules for what makes a POD (it isn’t always immediately obvious, since a single non-POD member variable makes a whole class non-POD).

    1. 4

      The D language did make a distinction there: struct is more POD (but not exactly because of RAII and similar, but it is value copied on assignment, has no vtable and so on) and class is more Java-style automatic references, virtual methods, etc. People coming from C++ regularly complain about this… it seems they love having both keywords be aliases to each other.

      1. 3

        The way C# did it was struct is a value type and class is a reference type; both can have functions et al (and prob a vtable as a result), but they do mean something different semantically.

        1. 1

          Given that there’s a meaningful distinction between POD and non-POD types, it seems to me that it’s good style to use class for non-POD structures. To me, using struct for these is just a way of showing off one’s mastery of C++ arcana, and IMO that kind of showing off has no place in professional programming.

        2. 4

          TIL in C++, enum class is the same thing as enum struct. Source: https://en.cppreference.com/w/cpp/language/enum

          1. 3

            I suggested the tag historical. Can someone second that?

            1. 2

              I’m glad the tag was added given it is a very old argument. Nonetheless, I read the article hoping that it would be something novel like repurposing the concept keyword.

            2. 3

              That’s just the tip of the iceberg: C++ style OOP in its current form should not exist. It should be like Go/Rust.

              • Private non-virtual functions are flawed: They have no business being in the same header, yet C++ artificially enforces declaring them in the class. It is silly that you need the pimpl idiom to work around that.
              • Private data is flawed: As soon as you have private state in a class, its member functions become untestable: In order for a function to be unittestable, the test must have full access to its input and its output, and state is both input and output.
              1. 2

                You can easily solve point two with #define class struct and #define private public.

                Warning: this medication may cause side effects.

              2. 1

                Since struct and class are so similar, I choose to consider class to be the keyword in excess, simply because struct exists in C and not class, and that it is the process of the keyword class that brought them both so close.

                This is an interesting perspective on the history. I would consider struct to be the keyword worth removing, since that would change the default access qualifiers to be safer.

                1. 5

                  I may be misremembering but I am reasonably sure that backwards compatibility with C was one of the early design goals of C++. Removing struct would quickly break compatibility. That is, presumably, why the default access qualifier is different from class‘s (and identical to C’s struct).

                  1. 1

                    It’s always irked me that this C compatibility was only one-way because of support for member functions (at least).

                  2. 3

                    Removing struct would create a lot more C code that is not C++, and making the default “safer” doesn’t improve things since, as noted, it’s standard practice to be explicit with access qualifiers.

                    1. 4

                      Yeah, I don’t think that can be understated. This would destroy one of the biggest reasons C++ was successful, and one of its main advantages to this day. It would even make most C headers not C++ compatible, which would be an absolute catastrophe. Even if the committee did something so egregious, no compiler could or would ever implement it (beyond perhaps a performative warning).

                      I think the real mistake is that the keywords are redundant at all. We’ve ended up with this near-universal convention that struct is for bags of data (ideally POD or at least POD-ish) because that’s a genuinely useful and important distinction. Since C++ somehow ended up with the useless “class except public by default” definition, we all simply pretend that it has a useful (if slightly fuzzy) one.

                      1. 1

                        Because of its incremental design and the desire to make classes seem like builtin types, C++ has a Moiré pattern-like feel. A lot of constructs that are exceedingly close, yet different.