TString, stdarg, variable argument list?

Hi, I have a named ROOT macro which I want to use with a variable argument list (using stdarg, unless there is a better option).

The beginning of the macro is as follows:

void standard_analysis(TString path_to_dir, TString argformat, ...)
{ 
  cout << path_to_dir << argformat << endl;
  va_list args;
  va_start(args,argformat);
  
  Int_t integration_time = va_arg(args,Int_t);
  Int_t cc_frames = va_arg(args,Int_t);
  Double_t cc_thresh = va_arg(args,Double_t);

  va_end(args);

For now I am hard-coding the access of the arguments and ignoring the format string, because this is being converted from older code which had fixed arguments.

The macro compiles, but a problem arises when I try to pass the TString arguments just using “strings”:

standard_analysis("../rootfiles/Outputs/Run0464","iif",8000,50,0.007)

 *** Break *** segmentation violation

but if I define the TStrings separately, it works:

root [13] TString fmt("iif")
root [14] TString ptd("../rootfiles/Outputs/Run0464")
root [15] standard_analysis(ptd,fmt,8000,50,0.007)
../rootfiles/Outputs/Run0464iif
...

This means that when I run the macro from the command line with root -b standard_analysis.C+(“path”,“format”,8000,50,0.007), I get the same segmentation fault as when using “strings”.

The older code looked like this:

void standard_analysis(TString path_to_dir, Int_t integration_time, Int_t cc_frames, Float_t cc_thresh){

and it worked fine passing the first argument either as a “string” or as an explicit TString, and also from the command line.

I’d appreciate any help in resolving this issue. I’d like to keep using TStrings because I do some manipulations in the code later to define paths.

Jean-François

I’ve found a solution/workaround/hack, but I’m still mystified by the problem.

My solution is to remove the explicit TString arguments from the function signature and instead use char *. Then in the script I create strings out of the char *. After this, the variable argument setup works. The new code looks like:

void standard_analysis(char * c_path_to_dir, char * c_argformat, ...)
{ 
  TString path_to_dir(c_path_to_dir);
  TString argformat(c_argformat);

  //cout << path_to_dir << argformat << endl;
  va_list args;
  va_start(args,c_argformat);
  
  Int_t integration_time = va_arg(args,Int_t);
  Int_t cc_frames = va_arg(args,Int_t);
  Double_t cc_thresh = va_arg(args,Double_t);

  va_end(args);
1 Like