TLatex affects random number generator after TCanvas::Print

I’ve come across a very strange problem involving TLatex, which affects the standard C++ random number generator. (I’m using Root 5.34.32).

When drawing a TLatex object to a canvas, and then printing that canvas, the state of the C++ random number generator is somehow affected. Here is a minimal program to demonstrate what happens:

#include <iostream>
#include "TCanvas.h"
#include "TLatex.h"

using namespace std;

int main()
{
  for(int i=0;i<10;++i){
    cout << rand() << endl;
  }
  TCanvas c("c","",100,100);
  TLatex l(0,0,"hello");
  l.Draw();
  c.Print("tst.png","png");
  cout << "-" << endl;
  for(int i=0;i<10;++i){
    cout << rand() << endl;
  }

  return(0);
}

If I run that multiple times, I get different random numbers in the second lot of 10 each time I run the program.

This behaviour only seems to occur for some print options (I’ve tested PDF, JPG and PNG files). If print out a root macro (.C), the sequence of random numbers is not affected.

What is going on here?

That sounds really weird. Have you tried to use the random number generator ROOT provide ?
I also see that you do not set the seed using srand…

Hi,

I filled a bug report:
sft.its.cern.ch/jira/browse/ROOT-7461

It seems to be fine w/ the current major version of ROOT, i.e. ROOT 6. It is fine as well when using ROOT in batch mode. Maybe that helps circumventing your problem for now.

Cheers,
Benedikt

I tried your example on Mac


{
   for (int i=0;i<10;++i) cout << rand() << endl;
////
//  TCanvas c("c","",100,100);
//   TLatex l(0,0,"hello");
//   l.Draw();
//   c.Print("tst.png","png");
/// 
   cout << "-" << endl;
   for (int i=0;i<10;++i) cout << rand() << endl;
}

Without or with the graphics commands between the 2 loops I get the same output with all ROOT versions.

16807
282475249
1622650073
984943658
1144108930
470211272
101027544
1457850878
1458777923
2007237709
-
823564440
1115438165
1784484492
74243042
114807987
1137522503
1441282327
16531729
823378840
143542612

Not sure if this helps, but there is no guarantee that rand() isn’t itself called within your C++ standard library between your explicit calls to it:

http://en.cppreference.com/w/cpp/numeric/random/rand

From my reading of that page, if you require reproducible random numbers with library calls in between, you can’t rely on std::rand(). There are other options that have better guarantees: http://en.cppreference.com/w/cpp/numeric/random

Disclaimer: This is just after a few minutes of googling about this problem, I am not an official C++ expert. = )
Jean-François