Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

constexpr for hash functions #686

Closed
wants to merge 1 commit into from
Closed

constexpr for hash functions #686

wants to merge 1 commit into from

Conversation

matbech
Copy link

@matbech matbech commented Apr 4, 2020

Description

constexpr for hash functions.

<type_traits> adds constexpr to the FNV-1a hash functions and helpers

<xstring> adds constexpr to struct hash<basic_string_view<_Elem, _Traits>>

Test and verification:
Verification for int, double, std::string_view
https://godbolt.org/z/jrqPg8

clang
-std=c++2a -O3
clang version 6 or higher, evaluates the function at compile time

MSVC
/std:c++latest /O3
MSVC 19.24, up MSVC 19.26.28720.3 does not evaluate the function at compile time.

Checklist

Before submitting a pull request, please ensure that:

  • Identifiers in product code changes are properly _Ugly as per
    https://eel.is/c++draft/lex.name#3.1 or there are no product code changes.

  • These changes introduce no known ABI breaks (adding members, renaming
    members, adding virtual functions, changing whether a type is an aggregate
    or trivially copyable, etc.).

  • Your changes are written from scratch using only this repository, the C++
    Working Draft (including any cited standards), other WG21 papers (excluding
    reference implementations outside of proposed standard wording), and LWG
    issues as reference material. If your changes are derived from a project
    that's already listed in NOTICE.txt, that's fine, but please mention it.
    If your changes are derived from any other project, you must mention it
    here, so we can determine whether the license is compatible and what else
    needs to be done.

<type_traits> adds constexpr to the FNV-1a hash functions and helpers

<xstring> adds constexpr to struct hash<basic_string_view<_Elem, _Traits>>

Test and verification:
Verification for int, double, std::string_view
https://godbolt.org/z/jrqPg8

clang
-std=c++2a -O3
clang version 6 or higher, evaluates the function at compile time

MSVC
/std:c++latest /O3
MSVC 19.24, up MSVC cl 19.26.28720.3 does not evaluate the function at compile time.
@matbech matbech requested a review from a team as a code owner April 4, 2020 20:50
Copy link
Contributor

@AdamBucior AdamBucior left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a maintainer but as far as I know non-standard extensions are not really welcome.

@@ -2177,7 +2177,7 @@ _NODISCARD inline size_t _Fnv1a_append_bytes(size_t _Val, const unsigned char* c
}

template <class _Ty>
_NODISCARD size_t _Fnv1a_append_range(const size_t _Val, const _Ty* const _First,
_NODISCARD constexpr size_t _Fnv1a_append_range(const size_t _Val, const _Ty* const _First,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function cannot be constexpr because of reinterpret_casts.

@@ -2186,21 +2186,21 @@ _NODISCARD size_t _Fnv1a_append_range(const size_t _Val, const _Ty* const _First
}

template <class _Kty>
_NODISCARD size_t _Fnv1a_append_value(
_NODISCARD constexpr size_t _Fnv1a_append_value(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function also contains reinterpret_cast.

const size_t _Val, const _Kty& _Keyval) noexcept { // accumulate _Keyval into partial FNV-1a hash _Val
static_assert(is_trivial_v<_Kty>, "Only trivial types can be directly hashed.");
return _Fnv1a_append_bytes(_Val, &reinterpret_cast<const unsigned char&>(_Keyval), sizeof(_Kty));
}

// FUNCTION TEMPLATE _Hash_representation
template <class _Kty>
_NODISCARD size_t _Hash_representation(const _Kty& _Keyval) noexcept { // bitwise hashes the representation of a key
_NODISCARD constexpr size_t _Hash_representation(const _Kty& _Keyval) noexcept { // bitwise hashes the representation of a key
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function calls _Fnv1a_append_value which contains reinterpret_cast.

return _Fnv1a_append_value(_FNV_offset_basis, _Keyval);
}

// FUNCTION TEMPLATE _Hash_array_representation
template <class _Kty>
_NODISCARD size_t _Hash_array_representation(
_NODISCARD constexpr size_t _Hash_array_representation(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another function with reinterpret_cast.

@matbech
Copy link
Author

matbech commented Apr 4, 2020

@AdamBucior Thank you for the review and you are correct. It clearly takes more than just adding constexpr to some functions.

@matbech matbech closed this Apr 4, 2020
@sylveon
Copy link
Contributor

sylveon commented Apr 5, 2020

It can be done, I myself use constexpr FNV1-a in my custom hashing code, but the codegen is worse than the one done here with reinterpret_cast.

@BillyONeal
Copy link
Member

I would not want this even if implementing it were 'free' because in vnext we want to replace this with something based on SipHash-2-4 where the hash values are not the same in successive runs of the program to make unordered_Xxx safe to use with untrusted input out of the box.

@StephanTLavavej
Copy link
Member

@AdamBucior

I'm not a maintainer but as far as I know non-standard extensions are not really welcome.

That's correct, as explained in https://github.com/microsoft/STL#non-goals .

We welcome the addition of [[nodiscard]] following our criteria, and the strengthening of noexcept (permitted by the Standard) in situations where it makes sense, but strengthening constexpr is currently forbidden by the Standard. Even if we increasingly think that strengthening constexpr should be permitted, we need to be careful about doing so, for the reason that @BillyONeal mentioned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants