繁体   English   中英

GCC __builtin_expect 在 constexpr 上下文期间检查临时指针的可空性导致奇怪的运行时行为

[英]GCC __builtin_expect checking pointer nullability of temporary during constexpr context results in strange run time behavior

我正在使用__builtin_expect在 constexpr function 中执行 null 指针检查,如下所示:

constexpr int Add(const int * x, const int * y)
{
    assert(__builtin_expect(!!(x && y), 1));
    return *x + *y;
}

我还有一个用于 const refs 的包装器方法,以允许传递临时对象:

constexpr int Add(const int & x, const int & y)
{
    return Add(&x, &y);
}

然后我使用临时对象创建一个全局常量:

static constexpr int result = Add(1, 2);

打印此值会导致0


int main() {
    std::cout << result; // 0
}

这里到底发生了什么?

删除__builtin_expect无法编译 GCC 抱怨与 constexpr 上下文中的临时变量的指针比较可能相关

神马

这是一个编译器错误,特别是https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85944

该问题与__builtin_expect无关。 它是关于常量表达式上下文中的 null 指针检查自身。 应该没问题。 在作为常量表达式求值期间,编译器知道指针引用的临时对象的生命周期跨越常量表达式求值的时间,因此不是 null。Add Add(1, 2)成为核心常量表达式的所有条件是使满意。

但是 GCC 似乎没有为命名空间 scope 中的临时对象正确处理此信息。如果result是一个块 scope 变量(有或没有static ),那么一切都按预期工作。

对于一个简单的解决方法,您当然可以在第二个重载中使用按值参数,或者您可以先将 arguments 存储在constexpr变量中,然后传递给Add 将初始化程序包装在 lambda 中以引入块 scope 可能也可以正常工作:

static constexpr int result = []{ return Add(1, 2); }();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM