Weird behavior defining a const int in a function in a loop

I ran across some weird behavior when trying to define a const int within or after a loop using a function. I’ve distilled everything down to the most basic example that reproduces the error.

#include <iostream>
using std::cout;
using std::endl;

void test1(int nVar)
{
    const int nVar2 = nVar;
    cout << "nVar: " << nVar << " const int nVar2: " << nVar2 << endl;
}

void test2(int nVar)
{
    int nVar2 = nVar;
    cout << "nVar: " << nVar << "       int nVar2: " << nVar2 << endl;
}

int main()
{
    const int centBins = 2;
    int nVar = 3;        

    cout << "Before loop" << endl;
    test1(nVar);
    test2(nVar);
    cout << endl;

    for (int centBin = 0; centBin < centBins; ++centBin)
    {
        cout << "Inside loop" << endl;
        test1(nVar);
        test2(nVar);
        cout << endl;
    }
    
    cout << "After loop" << endl;
    test1(nVar);
    test2(nVar);
    cout << endl;

    return 0;
}

When I compile this with:

I get the expected output:

Before loop
nVar: 3 const int nVar2: 3
nVar: 3       int nVar2: 3

Inside loop
nVar: 3 const int nVar2: 3
nVar: 3       int nVar2: 3

Inside loop
nVar: 3 const int nVar2: 3
nVar: 3       int nVar2: 3

After loop
nVar: 3 const int nVar2: 3
nVar: 3       int nVar2: 3

Everything looks as we would expect. Both functions recognize that nVar == 3 and that nVar2 should be assigned that value. When I run it through ROOT, however, I get the following:

root -b -q -l main.C

Before loop
nVar: 3 const int nVar2: 3
nVar: 3       int nVar2: 3

Inside loop
nVar: 3 const int nVar2: 0
nVar: 3       int nVar2: 3

Inside loop
nVar: 3 const int nVar2: 0
nVar: 3       int nVar2: 3

After loop
nVar: 3 const int nVar2: 0
nVar: 3       int nVar2: 3

(int)0

Before the loop nVar2 is set correctly in both the const and non-const functions but then you can clearly see that nVar2 is not being set correctly in const case when inside and after the loop.

I’m running:

ROOT 5.30/03 (tags/v5-30-03@41540, Oct 24 2011, 11:51:36 on linux)
CINT/ROOT C/C++ Interpreter version 5.18.00, July 2, 2010

Anyway, I wanted to get your guys’ take on this.

Hey,

funny thing is if one changes

to the equally valid

at least the outputs are the same.

Takeaway: Try to always compile your code, e.g. with ACLiC or outside of ROOT. Alternatively wait for cling.