Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is "assert (this)" a viable pattern?

Tags:

c++

Suppose the C++ below. Before calling of a->method1() it has an assert (a) to check if a is sane.

The call a->method2() has no such assertion; instead method2 itself checks for a valid this by means of assert (this).

It that viable code re. the C++ specification?

Even if it's covered by the standard, it not good style of course, and it's error prone if the code ever changes, e.g. if the method is refactored to a virtual method. I am just curios about what the standard has to say, and whether g++ code words by design or just by accident.

The code below works as expected with g++, i.e. the assertion in method2 triggers as intended, because just to call method2 no this pointer is needed.

#include <iostream>
#include <cassert>

struct A
{
    int a;
    A (int a) : a(a) {}

    void method1 ()
    {
        std::cout << a << std::endl;
    }

    void method2 ()
    {
        assert (this);
        std::cout << a << std::endl;
    }
};

void func1 (A *a)
{
    assert (a);
    a->method1();
}

void func2 (A *a)
{
    a->method2();
}

int main ()
{
    func1 (new A (1));
    func2 (new A (2));
    func2 (nullptr);
}

Output

1
2
Assertion failed: this, file main.cpp, line 16
like image 265
emacs drives me nuts Avatar asked Mar 10 '26 04:03

emacs drives me nuts


2 Answers

Even if it's [permitted] by the standard

It isn't.


it not good style of course

Nope.


and it's error prone if the code ever changes, e.g. if the method is refactored to a virtual method.

I concede that a virtual member function is more likely to cause a "crash" here, but you already have undefined behaviour and that's not just a theoretical concern: you can expect things like the assertion or conditions to be elided, or other weird things to happen.

This pattern is a big no-no.


I am just curios about what the standard has to say

It says:

[expr.ref/2] [..] For the second option (arrow) the first expression shall be a prvalue having pointer type. The expression E1->E2 is converted to the equivalent form (*(E1)).E2 [..]

[expr.unary.op/1] The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points. [..]

Notice that it doesn't explicitly say "the object must exist", but by saying that the expression refers to the object, it implicitly tells us that there must be an object. This sort of "gap" falls directly into the definition of undefined behaviour, by design.


whether g++ code words by design or just by accident.

The last one.

like image 133
Asteroids With Wings Avatar answered Mar 12 '26 01:03

Asteroids With Wings


Answering your question up front: "C++: Is "assert (this)" a viable pattern?" - No.

assert(this); is pointless. The C++ standard guarantees that the this pointer is never nullptr in valid programs.

If your program has undefined behaviour then all bets are, of course, off and this might be nullptr. But an assert is not the correct fix in that case, fixing the UB is.

like image 44
Jesper Juhl Avatar answered Mar 12 '26 00:03

Jesper Juhl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!