首页 文章

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

提问于
浏览
13

假设我有一个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 时进行编译 . 如果使用 test1 调用 FindMatchingIdx ,GCC将编译代码,但是如果使用 test2test3 调用 FindMatchingIdx ,GCC将无法编译代码,从而给出错误消息:

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

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

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

1 回答

  • 2

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

    如果标准在那里实际上是模糊的,那么gcc是正确的说 test1 != test2 未被标准指定 . 同时, test1==test1 由标准规定 .

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

相关问题