Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why I don't believe in the Rule of Zero

55 views
Skip to first unread message

Christopher Pisz

unread,
Nov 27, 2017, 7:31:12 PM11/27/17
to
Everyone is quick to point out the "Rule of Zero" in code reviews, peer conversations, and Stack Overflow comments/answers.

I am not a believer. I'd like to be. Usually if enough people agree on something enough for it to get its own label and become an idiom, then it is well thought out....

So, let me explain my reason for not believing:

I cannot count the number of times I have been tasked to debug a crash dump from a production crash. While debugging said dump, I can look up and down the call stack and sometimes I have the need to see "When is this class being constructed?" Secondarily, I might need to see "What is its or its members addresses when it is?" This usually leads to some other place in the code after evidence that more instances are being created than should be, or when addresses or sizes are not what is expected.

This could also apply, when I want to see "When is this class being assigned to?"

As such, I've always implement all 5 methods, trivial or not, in order to provide a place to break in future debug sessions while reproducing the conditions in the dump without having to change the source. Without them, there would be no way (easily) to perform the above debugging session.

If you modify source in order to provide a line of code to break on, your crash dump is no longer usable with the source.

Now, some would say that this situation does not arise often enough for them to add more code, and more potential bugs, in the case of trivial constructors and assignment operators. However, I'd argue that one occasion having to explain to your superiors that you have to make another build, redeploy to production, reproduce the crash, and retrieve another dump, in order to even start debugging the problem, is enough to change one's outlook. That is not an enjoyable experience and it has occurred to me a number of times.

So, please make me a believer!

Tell me how I can accomplish the above described debugging session given a crash dump, when there is no line available to break on, after being a good boy and following the "Rule of Zero".

Namely:

1) Break any time any instance of a given class is being constructed without any lines of constructor code to break on.

2) Break any time any instance of a given class is being assigned to without any lines of assignment operator to break on.

I am using Visual Studio, and more specifically Visual Studio 2015. I've heard people in *nix actually have a means to accomplish the task without lines to break on. I've never had the pleasure of being in that environment though. I'd think that even if it is only a problem for Windows users, that is still a good enough number of people to raise the discussion.

Alf P. Steinbach

unread,
Nov 27, 2017, 10:44:25 PM11/27/17
to
On 11/28/2017 1:31 AM, Christopher Pisz wrote:
>
> [snip] Tell me how I can accomplish the above described debugging
> session given a crash dump, when there is no line available to break
> on, after being a good boy and following the "Rule of Zero".
>
> Namely:
>
> 1) Break any time any instance of a given class is being constructed
> without any lines of constructor code to break on.
>
> 2) Break any time any instance of a given class is being assigned to
> without any lines of assignment operator to break on.
>
> I am using Visual Studio, and more specifically Visual Studio 2015.
> I've heard people in *nix actually have a means to accomplish the
> task without lines to break on. I've never had the pleasure of being
> in that environment though. I'd think that even if it is only a
> problem for Windows users, that is still a good enough number of
> people to raise the discussion.

Not addressing your problem but: it's more acute for basic types.

I once replaced a basic type with a full class type wrapper, for some
chosen variables, just for that kind of debugging. It wasn't my project.
These guys (re-) initialized their global variables from rather
inconceivable places at unpredictable times.

The order to not waste time on cleaning up the code was very firm. I
learned belatedly that it included not fixing bugs that prevented the
new code from functioning (that doesn't make sense, but not much did: my
theory is they were so incompetent as to be effectively insane). Half a
year later or so, questions about “what is this construction /for/”
appeared in this group, and I knew enough to answer them.


Cheers!,

- Alf

Öö Tiib

unread,
Nov 28, 2017, 4:55:09 AM11/28/17
to
On Tuesday, 28 November 2017 02:31:12 UTC+2, Christopher Pisz wrote:

<snipping to point>

> So, please make me a believer!

I use rule of zero as quite strong rule and can help to administer
it, but beware, my worldview is not a cult. It does not work on
belief. C++ is full of traps. Period. It is workable with awareness
understanding and on pile of tricks. If some "silver bullet" seems
to work always then it is actually superstition. You will be trapped
and then we all cheer "Gotcha!!". ;)

> Tell me how I can accomplish the above described debugging
> session given a crash dump, when there is no line available to break
> on, after being a good boy and following the "Rule of Zero".
>
> Namely:
>
> 1) Break any time any instance of a given class is being constructed
> without any lines of constructor code to break on.
>
> 2) Break any time any instance of a given class is being assigned to
> without any lines of assignment operator to break on.

Yes, our debuggers typically have no feature to break and to step
in implicitly generated code. When we only want to break or to trace
from the 5 then it is not too tricky to simplify it by typical separation
of concerns.

For example we can add a special member (or base) to our class with
all 5 members explicitly implemented. Implicitly-generated 5 are
required to call the 5 of such base or member and so we can break
in (or trace from) such stock class (or more likely template) instead
of implementing the 5 in every containing class.

That is already useful but we can further extend it with flexibility
features like:
1) to turn the fact of presence of such member on and off compile-time
2) to inject some other "indicating operations" besides trace into it
3) to select if it does its operation and from what members on and
off run-time
... and so on ...

As result instrumentation code can be left in forever and so can
be useful in unit-tests as well. Hopefully you see how to implement
such thing is lot more interesting and beneficial than to tediously
and error-pronely implement the 5 for each and every class.
0 new messages