https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86880

            Bug ID: 86880
           Summary: Incorrect mersenne_twister_engine equality comparison
                    between rotated states
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: hstong at ca dot ibm.com
  Target Milestone: ---

mersenne_twister_engines whose textual representation should be equal should
also compare equal.

The following program has two engines with initial states
|2 1 2
and
|3 1 2.

The engine with state |3 1 2 transitions to states
0 |1 2,
0 2 |2,
|0 2 1,
and
2 |2 1.

The textual representation of states |2 1 2 and 2 |2 1 are both specified to
be "2 1 2". That is, adjusted by rotation, the states are the same.

The engines are compared while in those states.
The comparison fails with libstdc++.

Online compiler: https://wandbox.org/permlink/RqdbiJZk6gVN0ici

Note: libstdc++ does not produce "2 1 2" as the textual representation
(as reported by PR 60441).


=== SOURCE (<stdin>):
#include <random>
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <cassert>

#ifdef TRACE
#include <iostream>
#undef TRACE
#define TRACE( X )  do { X } while(0)
#else
#define TRACE( X )  //
#endif

int main(void) {
  typedef unsigned int EngResType;

  constexpr size_t word_size = 3u;
  constexpr size_t state_size = 3u;
  constexpr size_t shift_size = 1u;
  constexpr size_t tempering_l = word_size;

  using namespace std;
  using EngineType = std::mersenne_twister_engine<
          EngResType, word_size, state_size,
          shift_size,
          0u,
          0x0,
          0u, 0x0,
          0u, 0x0,
          0u, 0x0,
          tempering_l,
          0>;

  EngineType mteA(0b010), mteB(0b011);
  TRACE( cout << "Engine A: " << mteA << endl;
         cout << "Engine B: " << mteB << "\n" << endl; );

  for (int i = 0; i < 4; ++i) {
    mteB();
    TRACE( cout << "Engine B: " << mteB << endl; );
  }

  TRACE( cout << "\nEngine A: " << mteA << endl;
         cout << "Engine B: " << mteB << endl; );

  assert(mteA == mteB);
}


=== COMPILER INVOCATION:
g++ -std=c++17 -pedantic-errors -Wall -Wextra -Werror -xc++ - -o ./a.out


=== RUN SCRIPT:
./a.out


=== EXPECTED RUN OUTPUT:
(Exits with rc=0).


=== ACTUAL RUN OUTPUT:
a.out: <stdin>:47: int main(): Assertion `mteA == mteB' failed.


=== COMPILER VERSION INFO:
Using built-in specs.
COLLECT_GCC=/opt/wandbox/gcc-head/bin/g++
COLLECT_LTO_WRAPPER=/opt/wandbox/gcc-head/libexec/gcc/x86_64-pc-linux-gnu/9.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../source/configure --prefix=/opt/wandbox/gcc-head
--enable-languages=c,c++ --disable-multilib --without-ppl --without-cloog-ppl
--enable-checking=release --disable-nls --enable-lto
LDFLAGS=-Wl,-rpath,/opt/wandbox/gcc-head/lib,-rpath,/opt/wandbox/gcc-head/lib64,-rpath,/opt/wandbox/gcc-head/lib32
Thread model: posix
gcc version 9.0.0 20180805 (experimental) (GCC)

Reply via email to