2016-10-07 60 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,但GCC將只編譯時FindMatchingIdx被調用數組中的第一個元素。如果FindMatchingIdx被調用test1,GCC將編譯代碼,但是如果FindMatchingIdx被調用test2test3 GCC將無法編譯代碼,給人的錯誤消息:

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

如果FindMatchingIdx有遞歸,GCC將未能將其視爲constexpr函數。這是GCC中的錯誤嗎?函數指針比較如何在constexpr函數內工作?顯然,它不能使用實際指針值,因爲鏈接器會指定這些值。

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

+0

它看起來像一個bug,可能是'operator!=(T,T)',其中'T'是一個函數指針不是'constexpr'而'operator ==(T,T)'它是。 – 101010

回答

2

我不知道這是爲什麼GCC抱怨,但在標準樣,如果test1test2有不同的地址,因此比較相等some arguable ambiguity

如果標準在那裏實際上是模棱兩可的,那麼gcc正確地說test1 != test2是標準沒有指定的。同時,test1==test1由標準規定。

函數指針的不等式具有這樣的好處,它允許編譯器使用相同的二進制實現將相同地址分配兩個不同的函數。因此,test1test2test3將是具有相同地址的不同函數,並且指向它們的指針會相等。

相關問題