How to make a macro with multiple functions

Hello, I’m quite new to ROOT and C++. I’m trying to write a macro with multiple functions for the first time, and I’ve run into some trouble. The below macro is saved as Task.c and consists of two functions that sort 20 randomly generated numbers from lowest to highest.

#include <iostream>
#include <cmath>
#include "TROOT.h"
using namespace std;

void longsort()
	{double unsorted[20];
	double sorted[20];
	double tempstorage=1;
	int smallestindex=0;
	for(int n=0; n<20; n++) unsorted[n]=gRandom->Uniform(1);
	for(int p=0; p<20; p++){
		for(int m=0; m<20; m++){
			if(unsorted[m]<tempstorage){tempstorage=unsorted[m]; smallestindex=m;}}
		sorted[p]=tempstorage;
		tempstorage=1;
		unsorted[smallestindex]=1;}
	for(int i=0; i<20; i++) cout << sorted[i] << ' ';
	}

void fastsort()
{	double abra[20];
	for(int n=0; n<20; n++) abra[n]=gRandom->Uniform(1);
	int nc=0;
	double tempstorage;
	bool swap=true;
	int q;
	while(swap==true){
		swap=false;
		for(q=0; q<19; q++){
			if(abra[q]>abra[q+1]){
				tempstorage=abra[q];
				abra[q]=abra[q+1];
				abra[q+1]=tempstorage;
				swap=true;
			}
			nc++;
	cout <<nc;
}}}

int main(){
	fastsort();
	return 0;
}

I’ve tested each of the functions (longsort and fastsort) individually, and I can run them just fine. However, when I define them as functions and run them through int main(), I run into a whole host of errors. When I execute it using .x Task.c++, I get the error “use of undeclared identifier ‘gRandom’” for both instances where I use gRandom.

When I execute it using .x Task.c, I get the error “Failed to call Task3() to execute the macro. Add this function or rename the macro. Falling back to .L.” I’ve tried using .L as well, but when I run main() or fastsort(), it gives me an absurdly large number for nc (the number of comparisons) whereas running fastsort as an independent macro gives a normal number for nc.

Finally, I tried getting rid of the header and executing the macro using .x Task.c, but I get the error “use of undeclared identifier ‘cout’”.

Please explain what I’m doing wrong. Thanks!


ROOT Version: 6.20.06
Platform: Windows 10
Compiler: Not Provided


In order to run the code as a ROOT macro, you’d need to define a function that matches the file name. ROOT macros use this function as an entry point instead of main(). In your case (Task.c), you’d need to define the function

void Task() {
  fastsort();
}

That should make .x Task.c (or root -l Task.c from the command line) work. The ROOT macro interpreter provides an environment that automatically loads ROOT components even if they are not explicitly imported through a #include line. When you hand your macro to the C++ compiler through .x Task.c++, you might need to add missing includes. In this case #include "TRandom.h" should fix the problem.

The main() function is only needed if you compile the code outside ROOT itself, for instance if you have a make file that calls g++ and links against ROOT libraries.

Just as a convention, ROOT macros usually end in a capital C instead of the lowercase c.

Cheers,
Jakob

1 Like

Hi Jakob,

That information was very helpful. Thanks!