2016-10-07 5 views
10

私は関数ポインタのconstexpr配列を持っていて、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); 

さて、このコードは、クランとMSVCでコンパイルをFindMatchingIdxが配列の最初の要素で呼び出されたとき、しかし、GCCはコンパイルされます。

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

FindMatchingIdxが再帰している場合は、GCCは以下となります。FindMatchingIdxtest1で呼び出された場合、GCCはFindMatchingIdxtest2またはtest3 GCCは、エラーメッセージを与えて、コードをコンパイルに失敗すると呼び出されたが場合、コードをコンパイルします。それをconstexpr関数として扱いません。これはGCCのバグですか?関数ポインタの比較は、constexpr関数の内部でもどのように機能しますか?明らかに、実際のポインタ値をリンカによって割り当てられた値として使用することはできません。

の作業例:https://godbolt.org/g/xfv1PM

+0

これはおそらく 'operator!=(T、T)'です。 'T'は関数ポインタが' constexpr'ではなく、 'operator ==(T、T)'です。 。 – 101010

答えて

2

これは gccが文句を言っているが、test1test2が別個のアドレスを持っている、したがって等しい比較する場合some arguable ambiguity約標準であり、なぜある場合、私は知りません。

標準が実際にあいまいである場合、標準ではtest1 != test2が指定されていないとgccは正しいです。一方、標準ではtest1==test1が指定されています。

関数ポインタの不等式は、コンパイラが同じバイナリ実装で同じアドレスを持つ2つの異なる関数を割り当てることができるという利点があります。従ってtest1test2test3は、同じアドレスを持つ別個の関数であり、それらのポインタは等しいと見なされます。

関連する問題