I'm sure everyone will think I'm crazy, but here goes...
Background:
I came across this problem while developing a proof of concept for my master's project. It entails generating random numbers according to either a uniform or a normal distribution. I wrote a few wrapper classes to simplify dealing with the generators and distributions. Those wrapper classes let me do this:
randomGenerator *rg;
if(uniformDistribution)
rg = new uniformGenerator();
else
rg = new normalGenerator();
(I also have constructors that take arguments to alter the range of values, but I'm not using them presently.) Then I can retrieve values like so:
(*rg)()
uniformGenerator and normalGenerator inherit from randomGenerator, and are wrappers for these:
boost::variate_generator<boost::minstd_rand&, boost::uniform_real<> >
boost::variate_generator<boost::minstd_rand&, boost::normal_distribution<> >
I currently have two programs that use those wrapper classes. One is fairly minimal; it simply parses some command line arguments that affect the distribution and quantity, then retrieves the values and prints them to stdout. The other program is my proof of concept; it does the same argument parsing (with a few more options), then makes use of the values to run my simulation, which is mostly manipulating STL containers.
Problem:
Now we come to the crazy part. I work mostly on one of two Windows machines, using g++ under Cygwin. On either machine, both of those programs run to completion every time, if I compile with -O1, -O2, or -O3. However, if I use -O0 (or just no -O argument), then the simulation locks up. The other program---that just prints random numbers---never locks up. (Incidentally, this program was my attempt to create a minimal program that replicated the behavior.) By single-stepping with gdb, I determined that it gets stuck in boost/random/uniform_01.hpp:
58 for (;;) {
59 result_type result = result_type(_rng() - (_rng.min)()) * _factor;
60 if (result < result_type(1))
61 return result;
62 }
gdb shows that result is always equal to 1, which of course leads to an infinite loop. Single-stepping through all of the code directly related to the random generators shows the same sequence of instructions for both programs. If I use the uniform distribution, it gets stuck when I try to retrieve the second value. If I use the normal distribution, it gets stuck on the third retrieval. Also worth noting, by default the generators are supplied with a different seed value every time I run either program.
Getting back to the programming environment, when I build on the Solaris machines in my school's CS department, the program never gets stuck. For my part, it's exactly the same source, and I still use g++. I have not been able to coerce any warnings or errors from the compiler. So, I'm all out of ideas. I'm open to suggestions for fixing this, but I'm hoping the solution is less extreme than compiling gcc from source.