Unexpected behavior of nested for loops when loading a macro with .L

Hi, I noticed what seems to be an unexpected behavior in Cling (ROOT 6.34.08, GCC 15.2.0, Linux). The following simple code works correctly when entered directly at the interactive prompt:

for (int i = 0; i < 10; ++i) {
for (int j = 0; j < 10; ++j) {
cout << i << " " << j << endl;
}
}

However, if I put exactly the same code in a file (not inside a void function) and load it with .L test_loop.C I get:

0 0
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9

The inner loop is executed only during the first iteration of the outer loop. Moreover, i and j remain visible in the interpreter:

root [1] i
(int) 10
root [2] j
(int) 10

If I put the same code inside a function and call the function the output is correct.
The same test with ROOT 6.28/08 produces a parsing error (expected unqualified-id) when the parser reaches the first for loop.

Thanks,
Alessandro

It could be a problem with your system or your ROOT. I don’t see the issue with the Ubuntu 24.04 binary of ROOT 6.34.08 (GCC 13.3), on Linux Mint. The ‘official’ download page (Release 63408 - ROOT) does not list any binary compiled with gcc 15.2.0 (the closest would be the MAC OS 15.4 version). You didn’t mention your OS or which ROOT binary (or compiled?), but if you are using a binary, it should be a version compiled with your same GCC version; otherwise, you should compile it yourself.

You try to use a so-called ROOT’s unnamed macro. Your source code must be enclosed in curly braces (I somehow remember that the “{” needed to be the very first line in a ROOT’s unnamed macro file):

{
 // ... your source code ...
}

BTW. To load and execute a macro, you should use “.x”, not “.L”.

With the curly braces it works. I thought it was illegal to use a for loop outside of any function (and why do the loop variables survive?). Perhaps the problem is with my own ROOT package: there is no package for Slackware Linux, so I built it myself.

Next time I’ll try the official packages first.

Thanks

couet@host-128-141-12-39 roottest % cat test_loop.C
void test_loop() {
   for (int i = 0; i < 10; ++i) {
      for (int j = 0; j < 10; ++j) {
         cout << i << " " << j << endl;
      }
   }
}%                                                                                                                                                                     couet@host-128-141-12-39 roottest % root           
   ------------------------------------------------------------------
  | Welcome to ROOT 6.41.01                        https://root.cern |
  | (c) 1995-2025, The ROOT Team; conception: R. Brun, F. Rademakers |
  | Built for macosxarm64 on Jun 25 2026, 14:10:57                   |
  | From heads/master@v6-39-99-744-gc60cc226368                      |
  | With Apple clang version 21.0.0 (clang-2100.1.1.101) std201703   |
  | Try '.help'/'.?', '.demo', '.license', '.credits', '.quit'/'.q'  |
   ------------------------------------------------------------------

root [0] .x test_loop.C
0 0
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
2 0
2 1
2 2
2 3
2 4
2 5
2 6
2 7
2 8
2 9
3 0
3 1
3 2
3 3
3 4
3 5
3 6
3 7
3 8
3 9
4 0
4 1
4 2
4 3
4 4
4 5
4 6
4 7
4 8
4 9
5 0
5 1
5 2
5 3
5 4
5 5
5 6
5 7
5 8
5 9
6 0
6 1
6 2
6 3
6 4
6 5
6 6
6 7
6 8
6 9
7 0
7 1
7 2
7 3
7 4
7 5
7 6
7 7
7 8
7 9
8 0
8 1
8 2
8 3
8 4
8 5
8 6
8 7
8 8
8 9
9 0
9 1
9 2
9 3
9 4
9 5
9 6
9 7
9 8
9 9
root [1] .q
couet@host-128-141-12-39 roottest % root test_loop.C
root [0] 
Processing test_loop.C...
0 0
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
2 0
2 1
2 2
2 3
2 4
2 5
2 6
2 7
2 8
2 9
3 0
3 1
3 2
3 3
3 4
3 5
3 6
3 7
3 8
3 9
4 0
4 1
4 2
4 3
4 4
4 5
4 6
4 7
4 8
4 9
5 0
5 1
5 2
5 3
5 4
5 5
5 6
5 7
5 8
5 9
6 0
6 1
6 2
6 3
6 4
6 5
6 6
6 7
6 8
6 9
7 0
7 1
7 2
7 3
7 4
7 5
7 6
7 7
7 8
7 9
8 0
8 1
8 2
8 3
8 4
8 5
8 6
8 7
8 8
8 9
9 0
9 1
9 2
9 3
9 4
9 5
9 6
9 7
9 8
9 9
root [1] .q
couet@host-128-141-12-39 roottest % 

@couet The question/problem was about an unnamed macro. Note this in the original post:

Perhaps the title is a bit misleading. My point is that code which is not valid C++ (i.e. a for loop outside any function) does not produce an error in my current ROOT build when I load the file with the .L command. With just one loop, the code works (the loop variable survives in any case). The code breaks when I add a nested loop.

I guess couet is right: there is probably something wrong with my current ROOT build.

Your “current ROOT build” is fine.

You said earlier that with curly brackets it is working. That’ s right, you were missing them in your first example. I then sent you two ways to execute a ROOT macro. First with .x macro.Cat the ROOT prompt then by putting directly the macro name after the root command. That’s simple and it should work with your ROOT build. I put a name in the macro file but it works the same way without. The only problem you had was the missing curly brackets.