0

I was recently reading Programming: Principles and Practice Using C++ (2nd Edition), and I came upon this snippet inside a function for inserting into a linked list (Page 619):

if (n==nullptr) return this;
if (this==nullptr) return n;

The first check seems fine, but the second check is very confusing to me. The question that immediately came to my mind is how this == nullptr can ever be true, considering that this would only equal nullptr if the object was instantiated as nullptr. Since this snippet is in a member function, one would have to dereference a null pointer to access it, which is undefined behavior. To confirm this, I created a small snippet:

#include <iostream>

class Test
{
public:
    Test() = default;
    void checkSelf()
    {
        if (this == nullptr)
        {
            std::cout << "This was nullptr.\n";
        }
        else
        {
            std::cout << "This was not nullptr.\n";
        }
    }
};

int main()
{
    Test* test; // Uninitialized pointer
    test->checkSelf(); // Outputs 'This was nullptr.'

    Test* test2 = nullptr;
    test2->checkSelf(); // Outputs 'This was nullptr.'

    Test* test3 = new Test{}; // Outputs 'This was not nullptr.'
    test3->checkSelf();

    delete test3;
}

And just as I expected, only when the pointer was uninitialized as in the first case (Well actually not expected here), or when it was set to nullptr as in the second case did the check evaluate to true inside the member function. However, since both examples where this was true were examples of undefined behavior, it makes no sense that the check could ever be true in a well-formed program. Thus, Can the check this == nullptr ever be true without invoking UB?

[GCC]

Arnav Borborah
  • 11,357
  • 8
  • 43
  • 88
  • 2
    All I can think of is that this slipped in from back when `this` *could* be null. – chris Feb 04 '18 at 23:02
  • @chris Care to elaborate? – Arnav Borborah Feb 04 '18 at 23:03
  • 2
    That is a godawful book BTW - Stroustrup has written some good books (The Design and Evolution of C++ is one of my favourites) but he isn't a great teacher. –  Feb 04 '18 at 23:03
  • @NeilButterworth that may be correct, but one should have some degree of expectations from the first and only book listed for beginners in our [book list](https://stackoverflow.com/a/388282/6525260)... – Arnav Borborah Feb 04 '18 at 23:04
  • 3
    A good explanation about this subject in the answer by Pavel Minaev in https://stackoverflow.com/questions/1844005/checking-if-this-is-null – Jorge Y. Feb 04 '18 at 23:04
  • 2
    Before the first ISO standard, you could change `this`. [This article](https://www.viva64.com/en/b/0355/) goes into more detail. Perhaps incidentally, the author of the code in question is the same in both cases. – chris Feb 04 '18 at 23:05
  • 1
    @ArnavBorborah Also true. The list should be modified to remove that one from the first place. – Ron Feb 04 '18 at 23:08
  • 1
    Probably because its the only even half-good book aimed at beginners. And I will never understand why people would choose C++ as their first language. –  Feb 04 '18 at 23:10
  • 4
    It seems Clang has also answered my question: `warning: 'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to false [-Wtautological-undefined-compare]` – Arnav Borborah Feb 04 '18 at 23:12
  • 1
    This has been up before. The example starts in the previous section, where it is not using member functions. Then it is converted to a `Link` class to show that one of the parameters can be replaced by `this`. But the conversion is not done properly, and some `if (p==0)` turned out as `if (this==0)`. – Bo Persson Feb 04 '18 at 23:14
  • @BoPersson Ah, that makes sense. – Arnav Borborah Feb 04 '18 at 23:20

0 Answers0