2017-08-07 62 views
1

我想我的哈希字符串與用戶定義在編譯時間之前字面 constexpr用戶定義的文字:是否允許?

constexpr unsigned int const_hash(char const *input) { 
    return *input ? 
     static_cast<unsigned int>(*input) + 33 * const_hash(input + 1) : 
     5381; 
} 

constexpr unsigned int operator ""_hash (const char *input, size_t) { 
    return const_hash(input); 
} 

int main(void) { 
    printf("%i\n", "test"_hash); 
    return 0; 
} 

它工作在GCC

mov esi, 2090770981 
mov edi, OFFSET FLAT:.LC0 
xor eax, eax 
call printf 

但不是MSVC

push  OFFSET [email protected][email protected][email protected]+1 
call  [email protected]@[email protected] 
mov  ecx, eax 
add  eax, 116 ; 00000074H 
shl  ecx, 5 
add  eax, ecx 
push  eax 
push  OFFSET [email protected][email protected][email protected] 
call  _printf 
add  esp, 12    ; 0000000cH 

所以我猜constexpr用戶定義文字是一個UB /編譯器實現?它是否在FDIS中指定?

(看,我知道遞歸constexpr功能是不允許的,但我使用它作爲一個例子)

編輯:

這裏有一個FNV-1非遞歸之一:http://godbolt.org/g/KF9BaE

這裏的一個DJB2非遞歸一個再次: http://godbolt.org/g/fsuFS9

0123: http://godbolt.org/g/7eJmpp

我可以通過安裝模板力不斷哈希行爲

但我將不會被允許的,因爲在字符串中參數文字已經衰減到指針

+0

「*看看我知道遞歸constexpr函數是不允許的,但我用它作爲示例*」您是否想過,也許這就是爲什麼它不起作用,而不是您使用UDL的事實?使用'constexpr'函數不能做的事情,UDL或不UDL似乎是值得懷疑的。 –

+0

不,我嘗試了各種constexpr C++哈希函數,包括crc32,fnv1,djb2,遞歸和非遞歸的函數,它們都共享類似的行爲。 –

+0

我在這裏使用的constexpr散列函數是一個djb2變體。 –

回答

0

您的上下文不要求constexpr字符串字面運營商預先評估的散列,所以它可以在運行時

完成
printf("%i\n", "test"_hash); 

你應該改變以

constexpr auto test_hash = "test"_hash; 
printf("%i\n", test_hash); 

您注意到的是編譯器的優化。

相關問題