允许在constexpr函数中进行函数指针比较吗?

Jon*_*anN 13 c++ language-lawyer constexpr c++11 c++14

假设我有一个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);
Run Code Online (Sandbox Code Playgroud)

现在这个代码在Clang和MSVC上编译,但是GCC只会FindMatchingIdx在使用数组中的第一个元素调用时进行编译.如果FindMatchingIdx调用test1,GCC将编译代码,但如果FindMatchingIdx调用,test2test3GCC将无法编译代码,给出错误消息:

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

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

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

Yak*_*ont 2

我不知道这是否是gcc 抱怨的原因,但是标准中关于 if和具有不同的地址,因此比较相等的问题存在一些有争议的歧义test1test2

如果标准实际上是不明确的,那么 gcc 的说法是正确的test1 != test2,标准未指定。同时,test1==test1由标准规定。

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