是否将 nullptr 取消引用到 lambda 函数未定义的行为?

Is dereferencing nullptr to lambda function undefined behaviour?

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));
}

通过规范和另一个问题 我无法理解 *f 是否是未定义的行为。规范中的哪些部分会使这种不是未定义的行为?

What sections in the spec would make this not undefined behaviour?

这个问题问错了。没有标准的一部分明确表示它是未定义的,而标准的另一部分却说它已定义的程序。

您 link 的问题是关于获取取消引用的空指针的地址。那不是你在这里做的。您在这里所做的是通过空指针调用成员函数。 (*f) (1) 表示 f->operator() (1)。这是明确无效的,如果 -fsanitize=undefined 选项,将在 运行 时使用 GCC 或 clang 失败,否则可能会由于优化器假设 f != null.

而导致不可预测的行为

引用自N4140(大致为C++14),但在其他版本的标准中没有区别:

9.3.1 Nonstatic member functions [class.mfct.non-static]

2 If a non-static member function of a class X is called for an object that is not of type X, or of a type derived from X, the behavior is undefined.