Greetings all,
Is it possible to craft a future-safe comparison operator (==) in C++?
The problem I faced was that we have a class with multiple members. We have a comparison operator to validate if instance-1 of the object has the same values as instance-2.
i.e. we can do
class blarg {
.....
};
.....
blarg b1(..initializers...);
blarg b2 = b1;
if (b1 == b2) {
... then do something ....
}
However, I had a co-worker that added a new member to the class, but failed to update the comparison operator. This lead to problems that took a while for us to figure out.
Is there a coding practice, I mean other than code review (that failed for us), or coding method, design, template, magic beans, whatever that could help avoid situations like this?
My first reaction was to use the memcmp
command. However, after reading the stack overflow entry for "Comparing structures in C vs C++" I see that this can be problematic due to C++ classes having more than just the member data inside.
How do others deal with this?
Thank you in advance for your help.
Well, the obvious solution is to be more careful when you extend the original class. :) "Being more careful" includes things like code reviews, things like that, but obviously this isn't fool proof.
So tackling this problem from a philosophical point of view, rather than a technical one, can often provide insight. The philosophy in this case is that of being a paranoid programmer. Assume that code you write today will be broken by some nitwit months or years from now. (Edit per @Noah's comments below: More often than not, that nitwit is myself. Being a paranoid programmer protects me from myself probably more than anyone else.) If you can do something to ensure that when the nitwit does break your code something fails before the product is shipped, that would help.
Two things I like to use are static assertions and unit tests. A static assertion can be used in your operator==
code to verify that the sizeof
your class is what you expect it to be. For example:
bool MyClass::operator==(const MyClass& rhs) const
{
static_assert(sizeof(MyClass) == sizeof(foo_) + sizeof(bar_))
...
}
...where foo_
and bar_
are member variables. This will break the compile when the size of the class has changed.
As static assertion usually takes the form of a template class that will fail to compile when the expression is false. This can be a little tricky to write (but it's an interesting exercise -- consider what happens if you try to add a char test_[0]
member to a class). Fortunately, this wheel has already been invented. See Boost for an example, and I think the new MSVC compiler comes with one as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With