C++ compiler throws error with stan code that parses OK

I have a Stan program that parses as syntactically correct (with rstan 2.18.1) but when I try to run it in the C++ compiler throws these errors

filebd97b70df70.cpp:100:491: error: invalid suffix on literal; C++11 requires a space between literal and identifier [-Wreserved-user-defined-literal]
        return stan::math::promote_scalar<fun_return_scalar_t__>(stan::model::rvalue(integrate_ode_rk45(integrand_ode_functor__(), rep_array(0.0,1), get_base1(theta,1,"theta",1), rep_array(get_base1(theta,2,"theta",1),1), rep_array(0.0,0), rep_array(x,1), x_i, pstream__), stan::model::cons_list(stan::model::index_uni(1), stan::model::cons_list(stan::model::index_omni(), stan::model::nil_index_list())), "integrate_ode_rk45(integrand_ode_functor__(), rep_array(0.0,1), get_base1(theta,1,"theta",1), rep_array(get_base1(theta,2,"theta",1),1), rep_array(0.0,0), rep_array(x,1), x_i, pstream__)"));
                                                                         
                       
filebd97b70df70.cpp:100:491: error: expected ')'
filebd97b70df70.cpp:100:85: note: to match this '('
        return stan::math::promote_scalar<fun_return_scalar_t__>(stan::model::rvalue(integrate_ode_rk45(integrand_ode_functor__(), rep_array(0.0,1), get_base1(theta,1,"theta",1), rep_array(get_base1(theta,2,"theta",1),1), rep_array(0.0,0), rep_array(x,1), x_i, pstream__), stan::model::cons_list(stan::model::index_uni(1), stan::model::cons_list(stan::model::index_omni(), stan::model::nil_index_list())), "integrate_ode_rk45(integrand_ode_functor__(), rep_array(0.0,1), get_base1(theta,1,"theta",1), rep_array(get_base1(theta,2,"theta",1),1), rep_array(0.0,0), rep_array(x,1), x_i, pstream__)"));
                                                                                    ^
filebd97b70df70.cpp:100:531: error: invalid suffix on literal; C++11 requires a space between literal and identifier [-Wreserved-user-defined-literal]
        return stan::math::promote_scalar<fun_return_scalar_t__>(stan::model::rvalue(integrate_ode_rk45(integrand_ode_functor__(), rep_array(0.0,1), get_base1(theta,1,"theta",1), rep_array(get_base1(theta,2,"theta",1),1), rep_array(0.0,0), rep_array(x,1), x_i, pstream__), stan::model::cons_list(stan::model::index_uni(1), stan::model::cons_list(stan::model::index_omni(), stan::model::nil_index_list())), "integrate_ode_rk45(integrand_ode_functor__(), rep_array(0.0,1), get_base1(theta,1,"theta",1), rep_array(get_base1(theta,2,"theta",1),1), rep_array(0.0,0), rep_array(x,1), x_i, pstream__)"));

My stan code is as follows:

functions {

 
// Example integrand
  real[] integrand_ode(real y, real[] f, real[] theta, real[] x, int[] x_i) {
    real df_dx[1]; // Do not change
    df_dx[1] =  exp(-y^2 - x[1]^2); // Function of x and y to be integrated
    return(df_dx);
  }
//User-defined function of x after y integrated out
  real[] first_integral(real x, real[] f, real[] theta, real[] x_r, int[] x_i) {
     
    return(integrate_ode_rk45(integrand_ode, 
                            rep_array(0.0, 1), // Do not change
                            theta[1], // ymin
                            rep_array(theta[2], 1), //(ymax, 1)
                            rep_array(0.0, 0), // Do not change
                            rep_array(x, 1), // Do not change
                            x_i)[1,]);// Do not change
  }
  // Final integration wrt x
  real second_integral(real[] bounds ) {
    int x_i[0];
    return(integrate_ode_rk45(  first_integral, 
                            rep_array(0.0, 1),// Do not change
                            bounds[1],   //xmin
                            rep_array(bounds[2], 1), // (xmax, 1)
                            bounds[3:4],// Do not change
                            rep_array(0.0, 0) , // Do not change
                            x_i)[1,1]);// Do not change

  }
 
}


data {
 real xmin;
 real xmax;
 real ymin;
 real ymax; 
 
}
transformed data{
real bounds[4];
bounds[1] = xmin;
bounds[2] = xmax;
bounds[3] = ymin;
bounds[4] = ymax;
}
 
model {}
generated quantities{
  real integral = second_integral(  bounds);
}

This code is an attempt to improve on the code that was the subject of https://discourse.mc-stan.org/t/expose-stan-functions-c-code-not-compliling/6045/6
using an approach suggested in https://discourse.mc-stan.org/t/passing-data-to-the-ode-integrator-in-user-defined-functions-for-double-integration/6053/4

I can replicate this with clang++

The actual error is

  Compilation ERROR, function(s)/method(s) not created! file3154312cad97.cpp:100:491: error: invalid suffix on literal; C++11 requires a space between literal and identifier [-Wreserved-user-defined-literal]

from C++

        return stan::math::promote_scalar<fun_return_scalar_t__>(stan::model::rvalue(integrate_ode_rk45(integrand_ode_functor__(), rep_array(0.0,1), get_base1(theta,1,"theta",1), rep_array(get_base1(theta,2,"theta",1),1), rep_array(0.0,0), rep_array(x,1), x_i, pstream__), stan::model::cons_list(stan::model::index_uni(1), stan::model::cons_list(stan::model::index_omni(), stan::model::nil_index_list())), "integrate_ode_rk45(integrand_ode_functor__(), rep_array(0.0,1), get_base1(theta,1,"theta",1), rep_array(get_base1(theta,2,"theta",1),1), rep_array(0.0,0), rep_array(x,1), x_i, pstream__)"));

With g++, it is a little different

file338f2a0a0c56.cpp:100:536: error: unable to find string literal operator ‘operator""theta’ with ‘const char [173]’, ‘long unsigned int’ arguments

It looks like the generated C++ doesn’t look quite right.

If this is supposed to be quoted:


"integrate_ode_rk45(integrand_ode_functor__(), rep_array(0.0,1), get_base1(theta,1,"theta",1), rep_array(get_base1(theta,2,"theta",1),1), rep_array(0.0,0), rep_array(x,1), x_i, pstream__)"

then the quotes inside for "theta" should be escaped.

I am still puzzled, Ben. Surely there should not be an error like this if I run Stan code that is syntactically correct? Did I do something wrong? If so, what do I need to do to put it right.
I do not speak C++ and had been hoping that I could avoid having to learn it. If I have to, I will…

If something parses (i.e. is syntactically correct) but when you try to compile it, an error is thrown, then it is a Stan bug irrespective of what the user wrote. In this case, I believe what you wrote actually should work.