Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can dangling pointer be equal to valid pointer during constant evaluation in C++?

During constant expression evaluation in C++17, shall the compiler consider any pointer addressing a valid object unequal to any pointer addressing an object after the end of its lifetime?

For example:

constexpr auto f(int * x = nullptr) {
    int c = 0;
    auto p = &c;
    if ( x == p )
        throw "unexpected";
    return p;
};

int main() {
    static_assert( f( f() ) );
}

Here the inner call of function f() returns a dangling pointer, which is passed to f again. I believed that the condition x == p must be false since x is a dangling pointer and p is a valid pointer, and it is indeed so in Clang. But in GCC the condition is satisfied and the constant evaluation fails due to throw. Demo: https://gcc.godbolt.org/z/ehcMro17q

Is it an undefined or implementation-defined behavior, or one of the compilers is wrong?

like image 424
Fedor Avatar asked Oct 07 '21 07:10

Fedor


People also ask

What is a dangling pointer?

The term dangling pointer means that whatever address in memory it points to is invalid. If you make it valid, like your 2nd malloc, then the address becomes valid. If you store the same address in two different variables (via your assumption) both are valid pointers:

How to test the validity of a pointer in C++?

There are no provisions in C++ to test for the validity of a pointer as a general case.

Can we modify the value of a constant pointer?

It does not allows modification of its value, however you can modify the value pointed by a pointer. In other words, constant pointer is a pointer that can only point to single object throughout the program. Note: You must initialize a constant pointer at the time of its declaration. Note: We use const keyword to declare a constant pointer.

How do you prevent dangling pointers in C?

// The pointer becomes dangling if it points to variable which has became out of scope. The following case of dangling pointer in C can be prevented by extending the scope of variable x outside the block.In that case memory will not be freed as controls come out of block.


1 Answers

The result of comparing a dangling pointer with any other pointer is implementation-defined:

When the end of the duration of a region of storage is reached, the values of all pointers representing the address of any part of that region of storage become invalid pointer values. […] Any other use of an invalid pointer value has implementation-defined behavior.

([basic.stc]/4) (equality comparison is included in “other use” here.)

As noted in the comments, even the lvalue-to-rvalue conversion of the comparison operands invokes implementation-defined behaviour for the invalid pointer ([conv.lval]/3.3). Unfortunately I can’t find anything that mandates lvalue-to-rvalue conversion for the operands of an equality comparison; [expr.eq]/2 at best implies this very indirectly.

like image 65
Konrad Rudolph Avatar answered Nov 04 '22 15:11

Konrad Rudolph