1
votes

I'm trying to hash my string with user-defined literal prior in compile time

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

It works in GCC

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

but not in MSVC

push     OFFSET ??_C@_04CEJDCDCH@test?$AA@+1
call     ?const_hash@@YAIPBD@Z
mov      ecx, eax
add      eax, 116   ; 00000074H
shl      ecx, 5
add      eax, ecx
push     eax
push     OFFSET ??_C@_03PELOGHMK@?$CFi?6?$AA@
call     _printf
add      esp, 12              ; 0000000cH

so I guess constexpr user-defined literals is an UB/compiler implementation? Is it specified in FDIS?

(Look I know recursive constexpr function is not allowed but I'm using it as an example)

Edit:

Here's a FNV-1 non-recursive one: http://godbolt.org/g/KF9BaE

Here's a DJB2 non-recursive one again: http://godbolt.org/g/7eJmpp

I could force the constant hash behavior by installing a template: http://godbolt.org/g/fsuFS9

but then I will not be allowed to pre-evaluate hash for string literal operator because the string literal in parameter is already decayed to pointer

1
"Look I know recursive constexpr function is not allowed but I'm using it as an example" Has it occurred to you that maybe that's why it's not working, rather than the fact that you're using a UDL? It seems questionable to use as a test a thing that constexpr functions cannot do, UDL or not.Nicol Bolas
no i tried various constexpr C++ hash functions, including crc32, fnv1, djb2, recursive and non-recursive ones, all of them shared a similar behavior.Steve Fan
The constexpr hash function I used here is a djb2 variant.Steve Fan
Then provide an example that is not recursive.Nicol Bolas
Pertinent information goes in the question, not the comments below. Feel free to edit your question and add those things to it.Nicol Bolas

1 Answers

0
votes

Your context does not require constexpr, so it can be done at runtime

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

You should change to

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

What you observe is optimization of compiler.