Compile-time comparison of pointers to local variables after their end of life

Viewed 132

Starting from C++17, it is possible to define a constexpr function that will return a pointer on its local variable. The caller will so get a pointer on an object after its end of life.

Clearly such pointers cannot be dereferenced to avoid undefined behavior. But is it legal to compare them on equality?

Consider an example:

constexpr auto f() {
    char c = 0;
    auto p = &c;
    return p;
};

int main() {
    static_assert( ( f() == f() ) == ( f() == f() ) ); //ok everywhere
    static_assert( f() == f() ); //true in GCC, false in Clang
}

The first static_assert is accepted by all compilers (if there is some undefined behavior, no single warning appear), and it basically checks that f() == f() gives consistent result true or false in each compiler.

GCC says that f() == f() is true, while Clang insists on f() != f() (which looks more logical for compile-time). Demo: https://gcc.godbolt.org/z/YG1jonoG7

Which compiler (if any) is right here?

1 Answers

This is, oddly, implementation-defined per [basic.stc]/4: the pointers returned by f are invalid, so comparing them might do something bad. Of course, it’s not really clear what the space of possibilities includes here: a footnote mentions a runtime fault, which is usually lumped with undefined behavior, but during constant evaluation one would expect that to reliably fail the evaluation (which would be reported as “static_assert expression not constant”). Supposedly, implementations are required to document their choice here, but I doubt any of them meaningfully address this particular situation.

Related