Bug 102531 - std::hash does not work correctly on Big Endian platforms
Summary: std::hash does not work correctly on Big Endian platforms
Status: RESOLVED DUPLICATE of bug 98731
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 8.4.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-09-29 16:44 UTC by mfarca
Modified: 2021-09-29 18:15 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description mfarca 2021-09-29 16:44:05 UTC
std::hash does not work correctly on BE machines using the following key types:
- std::hash<std::bitset>
- std::hash<std::vector<bool>>

They both break the 5th rule, a large number of inputs will end up having the same hash:
https://en.cppreference.com/w/cpp/utility/hash

### std::bitset
```
#include <iostream>
#include <functional>
#include <bitset>

int main(){
  std::bitset<2> a(0b01);
  std::bitset<2> b(0b10);

  std::size_t h1 = std::hash<std::bitset<2>>{}(a);
  std::size_t h2 = std::hash<std::bitset<2>>{}(b);

  std::cout << h1 << std::endl;
  std::cout << h2 << std::endl;
  return 0;

```
Output will be the same on BE machines.
The input length calculation is done incorrectly here:
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/bitset#L1575
`bitset` writes 0 extended size_t sized values into memory. Reading smaller lengths might return 0 as bytes are not reversed on BE.

### std::vector<bool>
```
#include <iostream>
#include <vector>
#include <functional>

int main(){
 
  std::vector<bool> a= {static_cast<bool>(1), static_cast<bool>(2)};
  std::vector<bool> b= {static_cast<bool>(1), static_cast<bool>(2), static_cast<bool>(3)};

  std::size_t h1 = std::hash<std::vector<bool>>{}(a);
  std::size_t h2 = std::hash<std::vector<bool>>{}(b);

  std::cout << h1 << std::endl;
  std::cout << h2 << std::endl;

   return 0;
}
```
Similar issue as bitset. vector<bool> writes size_t sized values into memory.
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/vector.tcc#L987
The calculated length in the above link might be smaller than the input and only 0s will get returned as bytes are not reversed on BE.
Comment 1 Jonathan Wakely 2021-09-29 18:15:07 UTC
dup

*** This bug has been marked as a duplicate of bug 98731 ***