Why does the enhanced GCC 6 optimizer break practical C++ code?

前端 未结 5 1994
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-28 03:19

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

5条回答
  •  半阙折子戏
    2020-11-28 04:06

    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.

提交回复
热议问题