Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is reading a variable outside its lifetime during constant evaluation diagnosable?

Shall one expect a reliable failure of in constant evaluation if it reads a variable outside of its lifetime?

For example:

constexpr bool g() {
    int * p = nullptr;
    {
        int c = 0;
        p = &c;
    }
    return *p == 0;
};

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

Here Clang stops with the error

read of object outside its lifetime is not allowed in a constant expression

But GCC accepts the program silently (Demo).

Are both compilers within their rights, or GCC must fail the compilation as well?

like image 504
Fedor Avatar asked Oct 05 '21 07:10

Fedor


People also ask

What happens to the value of a variable when it expires?

The value of a variable may change over its lifetime, but it retains some value. When a variable loses scope, it no longer has a value. When a procedure begins running, all variables are initialized.

What is the lifetime of a variable?

The time during which a variable retains its value is known as its lifetime. The value of a variable may change over its lifetime, but it retains some value. When a variable loses scope, it no longer has a value.

What happens to the value of a variable when a procedure calls?

If the procedure calls other procedures, the variable retains its value while those procedures are running as well. If a procedure-level variable is declared with the Static keyword, the variable retains its value as long as code is running in any module.

What happens to a variable when it loses scope?

When a variable loses scope, it no longer has a value. When a procedure begins running, all variables are initialized. A numeric variable is initialized to zero, a variable-length string is initialized to a zero-length string (""), and a fixed-length string is filled with the character represented by the ASCII character code 0, or Chr ( 0 ).


1 Answers

GCC dropped the ball.

[expr.const]

5 An expression E is a core constant expression unless the evaluation of E, following the rules of the abstract machine ([intro.execution]), would evaluate one of the following:

  • ...
  • an operation that would have undefined behavior as specified in [intro] through [cpp];
  • ...

Indirection via dangling pointer has undefined behavior.

[basic.stc.general]

4 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. Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior.

So the invocation of g() may not be a constant expression, and may not appear in the condition of a static_assert which must be constant evaluated.

The program is ill-formed.

The above quotes are from the C++20 standard draft, but C++17 has them too.

like image 85
StoryTeller - Unslander Monica Avatar answered Oct 19 '22 19:10

StoryTeller - Unslander Monica