GCC 6 has a new optimizer feature: It assumes that this is always not null and optimizes based on that.
Value range propagation now assum
It does so because the "practical" code was broken and involved undefined behavior to begin with. There's no reason to use a null this, other than as a micro-optimization, usually a very premature one.
It's a dangerous practice, since adjustment of pointers due to class hierarchy traversal can turn a null this into a non-null one. So, at the very least, the class whose methods are supposed to work with a null this must be a final class with no base class: it can't derive from anything, and it can't be derived from. We're quickly departing from practical to ugly-hack-land.
In practical terms, the code doesn't have to be ugly:
struct Node
{
Node* left;
Node* right;
void process();
void traverse_in_order() {
traverse_in_order_impl(this);
}
private:
static void traverse_in_order_impl(Node * n)
if (!n) return;
traverse_in_order_impl(n->left);
n->process();
traverse_in_order_impl(n->right);
}
};
If you had an empty tree (eg. root is nullptr), this solution is still relying on undefined behavior by calling traverse_in_order with a nullptr.
If the tree is empty, a.k.a. a null Node* root, you aren't supposed to be calling any non-static methods on it. Period. It's perfectly fine to have C-like tree code that takes an instance pointer by an explicit parameter.
The argument here seems to boil down to somehow needing to write non-static methods on objects that could be called from a null instance pointer. There's no such need. The C-with-objects way of writing such code is still way nicer in the C++ world, because it can be type safe at the very least. Basically, the null this is such a micro-optimization, with such narrow field of use, that disallowing it is IMHO perfectly fine. No public API should depend on a null this.