15

Suppose I have a constexpr array of function pointers, and I want to write a constexpr function to find the array index for a specified function.

I might have code like this:

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

Now this code compiles on Clang and MSVC, however GCC will only compile when FindMatchingIdx is called with the first element in the array. If FindMatchingIdx is called with test1, GCC will compile the code, however if FindMatchingIdx is called with test2 or test3 GCC will fail to compile the code, giving the error message:

error: '(test1 != test2)' is not a constant expression.

If FindMatchingIdx has to recurse, GCC will fail to treat it as a constexpr function. Is this a bug in GCC? How does function pointer comparison even work inside a constexpr function? Obviously it can't be using real pointer values as those are assigned by the linker.

Working example: https://godbolt.org/g/xfv1PM

Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
JonathanN
  • 233
  • 2
  • 5
  • It looks like a bug to me, that is probably `operator!=(T, T)` where `T` is a function pointer is not `constexpr` while `operator==(T, T)` it is. – 101010 Oct 07 '16 at 14:04

1 Answers1

2

I do not know if this is why gcc is complaining, but there is some arguable ambiguity in the standard about if test1 and test2 have distinct addresses, and hence compare equal.

If the standard is actually ambiguous there, then gcc is right in saying test1 != test2 is unspecified by the standard. Meanwhile, test1==test1 is specified by the standard.

The inequality of function pointers being like that has the benefit that it permits the compiler to assign two distinct functions with identical binary implementations the same address. So test1 and test2 and test3 would be distinct functions with the same address, and pointers to them would compare equal.

Community
  • 1
  • 1
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524