On 7/12/19 5:42 AM, Jonathan Wakely wrote:
On 12/07/19 10:24 +0200, Jakub Jelinek wrote:
On Mon, Jul 08, 2019 at 03:56:51PM -0600, Martin Sebor wrote:
A couple of GCC's Coding Conventions call to

  1) Use the struct keyword for plain old data (POD) types.
     https://www.gnu.org/software/gcc/codingrationale.html#struct

and

  2) Use the class keyword for non-POD types.
     https://www.gnu.org/software/gcc/codingconventions.html#Class_Use

This is a coding convention that has been added without any discussion
whatsoever on that, maybe it was some Google internal coding convention or
something, do we really want to enforce it rather than discuss
and decide what we actually want?

With my limited C++ knowledge, the main distinction between struct and class
when both can appear interchangeably is that struct defaults to public:

The default applies to class members and base classes, but that's the
*only* distinction.

and class defaults to private:, and I think it is best to use those that
way, rather than having tons of class ... { public: ... } everywhere.

There are many C++ class boolean properties, rather than just
POD vs. non-POD and we could pick any of them instead of this particular one
for the struct vs. class distinction if we wanted to enforce it, but why?

I'm also unconvinced that POD is a useful distinction. A class might
be a POD today, but then we decide to add a default constructor to it
(or if/when we move to C++11, add default member initializers to it).
Does that mean we need to replace struct with class to follow this
convention?

Or we might decide to add a std::string member to it, which stops it
being a POD. Should every reference to it be changed from struct to
class?

Right, that's a downside of such a convention.  It can be mitigated
(but not avoided completely) by eschewing the class-key in references
to the type if it's unambiguous.  The warning suggests to drop
the class-key when it's possible.  I didn't follow that suggestion
in the cleanup patch only out of concern that people used to seeing
the 'class' or 'struct' there might be bothered by its removal.

At the same time, adding a std::string member to A POD can have
serious ripple effects in a code base that assumes the struct is
a POD.  -Wclass-memaccess finds a subset of those but not nearly
all of them (I'd love to see a warning that detected more).

Personally I think "no user-defined constructors" might be a more
useful distinction than POD. This is not a POD (because of the
std::string member) but I don't see why it should be a class not a
struct:

struct A {
  std::string name;
  int id;
};

It looks like a fine struct to me :)

But the answer depends on the goal of the convention.  If it is
to make it clear to users of A whether it can be used in a context
that expects a "POD" (such as some GCC containers) then A would
have to be a class.  Ideally, the POD requirement would be enforced
by smarter warnings and/or by type traits and static assertions but
not all projects make use of those (yet).

From my personal POV, the main value of the warnings is in
helping achieve the consistency that GCC (and many other projects)
put a heavy emphasis on.  To that end, all one really needs is
-Wmismatched-tags.  In the absence of the POD struct convention,
the other two warnings might only help decide what class-key to
choose when defining a new type.

Martin

PS I'm using the term POD loosely here.

Reply via email to