3

The GNU C++ standard library has:

  struct _Hash_impl
  {
    static size_t
    hash(const void* __ptr, size_t __clength,
     size_t __seed = static_cast<size_t>(0xc70f6907UL))
    { return _Hash_bytes(__ptr, __clength, __seed); }
    /* etc. */
  }

as part of its implementation (and that's what it uses on strings, for example). Now, I want to use that code too... how can I access it, in a portable way (i.e. in a way which would work with clang's libc++, say)?

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • Are you looking for `std::hash`? http://en.cppreference.com/w/cpp/utility/hash – GManNickG Feb 20 '16 at 21:26
  • @GManNickG: I would have to build a string for that, won't I? IIRC, you can't just wrap a bunch of bytes in an `std::string`. – einpoklum Feb 20 '16 at 21:34
  • Ah, I get what you're saying now. The `std::hash` stuff is your only access to a standard hash interface, and sadly it's pretty under-specified. It doesn't have anything for combining hashes (say, to hash a tuple or array). Boost has a good hashing library if you want something portable, including hashes for ranges. – GManNickG Feb 20 '16 at 21:50
  • Or, obviously, just copy that code and call it your own hash and manage your own library. :) – GManNickG Feb 20 '16 at 21:51
  • @GManNickG: Your opinion about my idea below? – einpoklum Feb 20 '16 at 22:54

2 Answers2

4

No. You cannot access your compiler's internal implementation details in a portable way. How could that possibly work?

You cannot even be sure that the implementation will still be there after the next compiler update by the very same compiler vendor. Or worse, it may still compile fine but have different run-time behaviour. That's a maintainability nightmare and an endless debugging session waiting to happen.

If you need portability or backward compatibility in the future, implement your own hash function and mimic the behaviour of _Hash_impl.

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
0

I've been thinking maybe I can get the effect of boring down to the implementation without actually doing so. I haven't implemented this yet, but I believe it should work:

  1. Write a custom allocator my_allocator which does not allow reallocation
  2. We can now use the class std::vector<char, my_allocator> which wraps a raw buffer with an std::vector of sorts.
  3. Given void* buf and size in bytes n, we instantiate a wrapper vector: std::vector<int, my_allocator<int>> vec(n, {}, buf);
  4. Now std::hash(vec) FTW!

Due credit to @hvd for instructing me about this wrapping trick last year.

Community
  • 1
  • 1
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • I don't see how this is any more "portable access" to the implementation than any other use of `std::hash`. It seems that all this accomplishes is a tautology: in order to access the implementation, you access the implementation via the interface. – Christian Hackl Feb 20 '16 at 23:07
  • Did you try this? I don't think `std::hash` is defined for your type. It's defined for `std::vector`, though, but not for `std::vector` in general (again, because ultimately the existing standard has no concept of combining hashes, so hashing a tuple or range isn't supported). Maybe some magic could get your bytes to act as bits in a `std::vector`, but just using Boost.Hash is going to be way cleaner and easier (and probably faster). – GManNickG Feb 20 '16 at 23:07
  • @ChristianHackl: You just said I can't access the implementation, but if this works (which it might not) - I can. That is, this will execute the internal hash primitive on (untyped) data of arbitrary length. – einpoklum Feb 20 '16 at 23:53
  • @GManNickG: Boost.Hash is perfectly fine in and of itself, but - it's not what I was trying to achieve (also I would like to limit my library dependencies). – einpoklum Feb 20 '16 at 23:54
  • @einpoklum: I don't think it works anyway. If I try to do what you say, VC gives me `error C2338: The C++ Standard doesn't provide a hash for this type`. – Christian Hackl Feb 21 '16 at 00:04
  • @ChristianHackl: GCC 5.x seems to have it. I wonder what about libc++. – einpoklum Feb 21 '16 at 00:08