在持续评估期间读取超出其生命周期的变量是否可以诊断?

Fed*_*dor 8 c++ language-lawyer constexpr c++17

如果读取超出其生命周期的变量,是否会期望在持续评估中出现可靠的失败?

例如:

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

int main() {
    static_assert( g() );
}
Run Code Online (Sandbox Code Playgroud)

这里 Clang 因错误而停止

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

int main() {
    static_assert( g() );
}
Run Code Online (Sandbox Code Playgroud)

但GCC默默地接受该程序(Demo)。

两个编译器都在其权利范围内,还是 GCC 也必须编译失败?

Sto*_*ica 7

GCC 失败了。

[表达式.const]

5表达式 E 是核心常量表达式,除非对 E 的求值遵循抽象机 ([intro.execution]) 的规则,将求值以下其中一项:

  • ...
  • 具有 [intro] 到 [cpp] 中指定的未定义行为的操作;
  • ...

通过悬空指针的间接具有未定义的行为。

[基础.stc.通用]

4当到达存储区域的持续时间结束时,表示该存储区域的任何部分的地址的所有指针的值变为无效指针值。通过无效指针值进行间接寻址以及将无效指针值传递给释放函数具有未定义的行为。对无效指针值的任何其他使用都具有实现定义的行为。

因此, 的调用可能不是常量表达式,并且可能不会出现在必须计算常量g()的条件中。static_assert

该程序格式不正确。

上面的引用来自 C++20 标准草案,但 C++17 也有。