【问题标题】:Is function pointer comparison in a constexpr function allowed?是否允许在 constexpr 函数中进行函数指针比较?
【发布时间】:2017-02-16 13:16:47
【问题描述】:

假设我有一个 constexpr 函数指针数组,我想编写一个 constexpr 函数来查找指定函数的数组索引。

我可能有这样的代码:

void test1(){}void test2(){}void test3(){}void test4(){}

typedef void(*func)(void);
constexpr func funcs[] = { &test1, &test2, &test3 };

constexpr int FindMatchingIdx (const func work, const int idx) {
    return (work == funcs[idx]) ? (idx) : (FindMatchingIdx(work, idx + 1));
}

constexpr unsigned int loc = FindMatchingIdx (&test1,0);

现在这段代码可以在 Clang 和 MSVC 上编译,但是 GCC 只有在使用数组中的第一个元素调用 FindMatchingIdx 时才会编译。如果FindMatchingIdxtest1 调用,GCC 将编译代码,但是如果FindMatchingIdxtest2test3 调用,GCC 将无法编译代码,并给出错误消息:

错误:'(test1 != test2)' 不是常量表达式。

如果FindMatchingIdx 必须递归,GCC 将无法将其视为 constexpr 函数。这是 GCC 中的错误吗?函数指针比较如何在 constexpr 函数中工作?显然它不能使用真正的指针值,因为它们是由链接器分配的。

工作示例:https://godbolt.org/g/xfv1PM

【问题讨论】:

  • 对我来说它看起来像一个错误,这可能是 operator!=(T, T) 其中T 是一个函数指针不是constexproperator==(T, T) 它是。

标签: c++ c++11 c++14 language-lawyer constexpr


【解决方案1】:

我不知道这是否是为什么 gcc 在抱怨,但标准中有some arguable ambiguity 关于test1test2 是否有不同的地址,因此比较相等。

如果那里的标准实际上是模棱两可的,那么 gcc 说 test1 != test2 没有被标准指定是正确的。同时test1==test1是标准规定的。

这样的函数指针不等式的好处是,它允许编译器为具有相同二进制实现的两个不同函数分配相同的地址。所以test1test2test3 将是具有相同地址的不同函数,并且指向它们的指针将比较相等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-05
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多