[Bug libstdc++/85439] New: mt19937_64 producing unexpected result only in certain configuration

2018-04-17 Thread foddex at foddex dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85439

Bug ID: 85439
   Summary: mt19937_64 producing unexpected result only in certain
configuration
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: foddex at foddex dot net
  Target Milestone: ---

Created attachment 43967
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43967&action=edit
Code mentioned in report

My sincere apologies if this doesn't belong here, I'm not a regular.

In my tests to establish STL's mersenne twister's reproducability, I have found
an interesting problem that I think is a bug in the libstdc++ runtime in Linux,
but I may be wrong.

I ran the attached code on the various platforms and compiler combinations:
LINUX:
- g++ version 7.3.1 20180130 (Red Hat 7.3.1-2) on Fedora 26 4.12.14-300
- clang++ version 4.0.1 (tags/RELEASE_401/final) on Fedora 26 4.12.14-300
- clang++ version 6.0.0 (tags/RELEASE_600/final) on Arch Linux 4.15.13-1
OSX:
- clang++ 9.1.0 Apple LLVM on High Sierra
WINDOWS:
- MSVC2017 15.6.6 on Windows 10

For g++ and clang++ the compilations options are identical on all platforms:
main.cpp -std=c++11

On MSVC a default solution was used.

The output on Linux is as follows:
32 bits gen, uint32_t: 3499211612
32 bits gen, uint64_t: 15028999435905310454
64 bits gen, uint32_t: 3379370269
64 bits gen, uint64_t: 14514284786278117030
32 bits gen, float: 0.814724
64 bits gen, float: 0.786821
32 bits gen, double: 0.135477
64 bits gen, double: 0.786821

The output of the clang++ on OS X and MSVC applications is as follows:
32 bits gen, uint32_t: 3499211612
32 bits gen, uint64_t: 15028999435905310454
64 bits gen, uint32_t: 4143361702
64 bits gen, uint64_t: 14514284786278117030
32 bits gen, float: 0.814724
64 bits gen, float: 0.786821
32 bits gen, double: 0.135477
64 bits gen, double: 0.786821

Note that the output only differs on the 3rd line. 

Since MSVC and clang agree on all tests, and their implementations are
independent, I came to the conclusion it must be a bug in libstd++ on Linux.

[Bug libstdc++/85439] mt19937_64 producing unexpected result only in certain configuration

2018-04-18 Thread foddex at foddex dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85439

--- Comment #1 from Marc "Foddex" Oude Kotte  ---
When one adds std::hex output formatting for the first four std::cout calls,
for example the first line would then look like:

std::cout << "32 bits gen, uint32_t: " << std::hex <<
generateRandom() <<
std::endl;

The output on MSVC and OSX becomes:
32 bits gen, uint32_t: d091bb5c
32 bits gen, uint64_t: d091bb5c22ae9ef6
64 bits gen, uint32_t: f6f6aea6
64 bits gen, uint64_t: c96d191cf6f6aea6

And the output on Linux becomes:
32 bits gen, uint32_t: d091bb5c
32 bits gen, uint64_t: d091bb5c22ae9ef6
64 bits gen, uint32_t: c96d191d
64 bits gen, uint64_t: c96d191cf6f6aea6

A number of observations:
- on line 3, MSVC + OSX seem to return the lower 32 bits of line 4
- on line 3, Linux seems to return the upper 32 bits of line 4, with 1 added
But:
- on line 1, everybody just seems to return the upper 32 bits of line 2

I am at a loss who is right here.

[Bug libstdc++/85439] mt19937_64 producing unexpected result only in certain configuration

2018-04-19 Thread foddex at foddex dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85439

--- Comment #4 from Marc "Foddex" Oude Kotte  ---
The reason I was expecting the same result everywhere is because of this
statement on cppreference.com:


"Notes
The 1th consecutive invocation of a default-contructed std::mt19937 is
required to produce the value 4123659995.

The 1th consecutive invocation of a default-contructed std::mt19937_64 is
required to produce the value 9981545732273789042"


Source: http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine

Obviously I'm not testing the 1th consecutive invocation but the 1st, but I
still expected things to be similar (and they are, in 7/8 test cases).

[Bug libstdc++/85439] mt19937_64 producing unexpected result only in certain configuration

2018-04-19 Thread foddex at foddex dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85439

--- Comment #7 from Marc "Foddex" Oude Kotte  ---
OK. My apologies for the confusion, and thanks for the clarification!

[Bug c++/66670] "template argument deduction/substitution failed" with function pointers and multiple parameter packs

2018-09-13 Thread foddex at foddex dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66670

Marc "Foddex" Oude Kotte  changed:

   What|Removed |Added

 CC|        |foddex at foddex dot net

--- Comment #2 from Marc "Foddex" Oude Kotte  ---
I have a similar problem with only one parameter pack, that I think is closely
related to this bug.

The following code does not work with gcc 8.1.1, gcc 8.2 and Apple LLVM version
9.1.0, but does work with MSVC 2017 15.8.4 and icc 18.0.0 (as checked with
https://godbolt.org)


template
static void whatever(_Object*, void(_Object::*method)(_Parameters..., float))
{}

struct Foobar {
void myMethod(bool, float);
};

int main(int argc, char** argv) {
Foobar f;
whatever(&f, &Foobar::myMethod);
}


When compiled with -std=c+=14, gcc's output is:

: In function 'int main(int, char**)':
:10:49: error: no matching function for call to 'whatever(Foobar*, void (Foobar::*)(bool, float))'
 whatever(&f, &Foobar::myMethod);
 ^
:2:13: note: candidate: 'template
void whatever(_Object*, void (_Object::*)(_Parameters ..., float))'
 static void whatever(_Object*, void(_Object::*method)(_Parameters..., float))
{}
 ^~~~
:2:13: note:   template argument deduction/substitution failed:
:10:49: note:   mismatched types 'float' and 'bool'
 whatever(&f, &Foobar::myMethod);

 ^

Note that the following version of the above code DOES work perfectly, on all
aforementioned mentioned compiler versions.


template
static void whatever(_Object*, void(_Object::*method)(float, _Parameters...))
{}

struct Foobar {
void myMethod(float, bool);
};

int main(int argc, char** argv) {
Foobar f;
whatever(&f, &Foobar::myMethod);
}


The difference is that in the first version, the parameter pack comes first,
and then the fixed float parameter, while in the second version, the float
comes first, and then the parameter pack.


Hope this helps