【问题标题】:Is dereferencing nullptr to lambda function undefined behaviour?是否将 nullptr 取消引用到 lambda 函数未定义的行为?
【发布时间】:2023-03-11 21:05:02
【问题描述】:

正如pfultz2 所示,有一种解决方法来静态初始化 lambda 函数。其中一个步骤提到取消引用指向 lambda 函数类型的指针的 nullptr。

template <typename T> typename std::remove_reference <T>::type * addr (T && t)
{
    return & t;
}

constexpr auto f = true ? nullptr : addr ([] (int arg) { return arg + 1; });

int main ()
{
    assert (((*f) (1) == 2));
}

查看规范和另一个问题C/C++ nullptr dereference 我很难理解*f 是否是未定义的行为。规范中的哪些部分会使这种 not 行为未定义?

【问题讨论】:

    标签: c++11 lambda static-initialization


    【解决方案1】:

    规范中的哪些部分会使这种行为不是未定义的?

    这是一个错误的问题。没有程序中标准的一部分明确表示它未定义,而标准的另一部分则表示无论如何都已定义。

    您链接到的问题是关于获取取消引用的空指针的地址。那不是你在这里做的。您在这里所做的是通过空指针调用成员函数。 (*f) (1) 表示 f-&gt;operator() (1)。这显然是无效的,如果 -fsanitize=undefined 选项在运行时使用 GCC 或 clang 将失败,并且可能由于优化器假设 f != null 而导致不可预测的行为。

    引用自 N4140(大致 C++14),但在其他版本的标准中并没有什么不同:

    9.3.1 非静态成员函数 [class.mfct.non-static]

    2 如果为非 X 类型或从 X 派生的类型的对象调用类 X 的非静态成员函数,则行为未定义。

    【讨论】:

    • 谢谢,当你指出这一点时,现在看起来很明显。我迷失在隐式转换中,谁知道呢!
    猜你喜欢
    • 1970-01-01
    • 2013-04-16
    • 2017-02-17
    • 2020-11-29
    • 2011-10-11
    • 1970-01-01
    • 2018-07-11
    • 2018-08-22
    • 1970-01-01
    相关资源
    最近更新 更多