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::variate_generator >
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.