Jump to content
  • Advertisement
Sign in to follow this  
SeeForever

[C++] Curious problem with rand()

This topic is 2106 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This isn't a problem per se as I have solved it, but it intrigues me.

 

Basically rand() isn't generating the same sequence of numbers for the same seed. My program is very long and split into over 40 classes so it wouldn't make sense to post everything here, but check this: after 2 days of playing around with different parts of my code I ended up replacing every call to rand() and srand() to custom versions, and now everything works fine. Now I run my program 10 times with the same seed and it always generates identical output, but that is not the case with the stdlib version.

 

I tried to reproduce this by writing a small program that outputs rand() results to files but it works as expected so I'm guessing either the C/C++ runtime or one of the third-party libraries I'm using is calling rand() behind the scenes at some point. Is that possible or is all this just a coincidence somehow?

 

I'm using the following software:

  • Compiler: MinGW 4.7.2
  • Libraries: SDL 2.0.0 along with SDL_Image and the png/zlib libraries it comes with

Thanks in advance if anyone knows.

Share this post


Link to post
Share on other sites
Advertisement

 

so I'm guessing either the C/C++ runtime or one of the third-party libraries I'm using is calling rand() behind the scenes at some point. Is that possible or is all this just a coincidence somehow?

Either your own code has another srand/rand hidden in it somewhere that you've missed, or a bit of 3rd party code does.
That sounds like the only logical explanation.

 

This is why globals/singletons are bad dry.png

 

I thought so. I don't want to blame SDL of messing with the state of rand() but I don't see how my code could be doing it, if it runs fine with my custom version. ;-;

Share this post


Link to post
Share on other sites


I thought so. I don't want to blame SDL of messing with the state of rand() but I don't see how my code could be doing it, if it runs fine with my custom version. ;-;

 

You should be able to step into a rand() call a bit to find the memory address of the seed and place a data breakpoint on it.

Share this post


Link to post
Share on other sites
You should use the new C++11 random header instead of rand; it solves this problem, and gives you better guarantees about uniform results.

Share this post


Link to post
Share on other sites

Often, If you use static initialization on a global level, you can't tell which order the objects are created in.

Usage of rand() here may cause code invoking rand() in a different order than expected.

Of course, if the same build is causing different sequences, that's a different thing ohmy.png.

 

(Also, i must agree with Mir, stl http://www.cplusplus.com/reference/random/ is really sweet - I use it a lot.)

Edited by SuperVGA

Share this post


Link to post
Share on other sites

 

so I'm guessing either the C/C++ runtime or one of the third-party libraries I'm using is calling rand() behind the scenes at some point. Is that possible or is all this just a coincidence somehow?

Either your own code has another srand/rand hidden in it somewhere that you've missed, or a bit of 3rd party code does.
That sounds like the only logical explanation.

 

This is why globals/singletons are bad dry.png

 

Hehe, agreed.

 

 

You should use the new C++11 random header instead of rand; it solves this problem, and gives you better guarantees about uniform results.

I've looked into that. It's a but too hardcore for my current needs.

 

 

Often, If you use static initialization on a global level, you can't tell which order the objects are created in.

Usage of rand() here may cause code invoking rand() in a different order than expected.

Of course, if the same build is causing different sequences, that's a different thing ohmy.png.

 

(Also, i must agree with Mir, stl http://www.cplusplus.com/reference/random/ is really sweet - I use it a lot.)

What do you mean by "static initialization on a global level"? Like initializing global variables outside of a function? I avoid doing that. :P

Share this post


Link to post
Share on other sites

What do you think the random seed is if not a global variable initialised outside a function (and modified by calling rand(), or srand()).

 

You already found 1 solution (roll your own replacement or better make a class that encapsulates a specific seed so you can use a separate random generator per class instance).

 

and uniform_real_distribution and uniform_int_distribution probably aren't as scary as they probably look... (example here http://www.cplusplus.com/reference/random/uniform_int_distribution/ )

 

The names are a tad verbose though ;)

Edited by Paradigm Shifter

Share this post


Link to post
Share on other sites

and uniform_real_distribution and uniform_int_distribution probably aren't as scary as they probably look... (example here http://www.cplusplus.com/reference/random/uniform_int_distribution/ )

 

The names are a tad verbose though ;)

 

Aliases/typedefs to the rescue! wink.png

using random_gen = std::uninform_int_distribution;

Are you sure your own code isn't calling rand() somewhere inbetween two calls? Generally, I assume my own code is the problem rather than the standard library - though it's possible that there is some bug, the majority of the time, I eventually find out my own code is the source of the bug.

 

Do a Ctrl+F for rand() and srand(), and see where else your own code might be interfering. Any call to rand() or srand() elsewhere in your code will mess up the sequence - this is one of the problems the new random generators solve (you can have separate generators for each purpose that requires it).

 

If you think SDL 2.0 calls it (SDL 1.6 didn't, afaik), you could do a Ctrl+F for 'rand' in SDL's source code.

Edited by Servant of the Lord

Share this post


Link to post
Share on other sites

Dropping frames due to frame rate and calling rand() in dropped frames is a culprit too.

 

Class solution is the best, don't let your logic, frame rate independent calls interfere with rand called for graphics. And so on. Some random numbers are more crucial than others (e.g. smoke effects, can look a bit different, random decisions of enemies wants to stay the same otherwise cascading lack of random sync effects start happening. This is the butterfly effect for computer programs).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!