Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempting to assign to a function name produces uncompilable C++ #1101

Closed
WardBrian opened this issue Jan 27, 2022 · 0 comments · Fixed by #1131
Closed

Attempting to assign to a function name produces uncompilable C++ #1101

WardBrian opened this issue Jan 27, 2022 · 0 comments · Fixed by #1131
Labels
bug Something isn't working robustness

Comments

@WardBrian
Copy link
Member

Current Behavior:

The following Stan model compiles in stanc3:

functions {
   real foo(int x){
     return 1.0;
   }

   real bar(int y){
     return 2.0;
   }

   void baz(){
     // NB: putting this in later blocks produce an error due to assigning to a global variable
     foo = bar;
   }
}

model {
     print(foo(1));
    baz();
   print(foo(1));
}

but the C++ fails to compile:

Cmdstan output
Building fun.stan
make: Entering directory '/home/brian/Dev/cpp/cmdstan'
cd /home/brian/Dev/ml/stanc3 && echo "--- Rebuilding stanc ---\n" && dune build @install
--- Rebuilding stanc ---\n
cp /home/brian/Dev/ml/stanc3/_build/default/src/stanc/stanc.exe bin/stanc

--- Translating Stan model to C++ code ---
bin/stanc  --o=../../ml/stanc3/fun.hpp ../../ml/stanc3/fun.stan

--- Compiling, linking C++ code ---
g++ -std=c++1y -pthread -D_REENTRANT -Wno-sign-compare -Wno-ignored-attributes      -I stan/lib/stan_math/lib/tbb_2020.3/include    -O3 -I src -I stan/src -I lib/rapidjson_1.1.0/ -I lib/CLI11-1.9.1/ -I stan/lib/stan_math/ -I stan/lib/stan_math/lib/eigen_3.3.9 -I stan/lib/stan_math/lib/boost_1.75.0 -I stan/lib/stan_math/lib/sundials_6.0.0/include -I stan/lib/stan_math/lib/sundials_6.0.0/src/sundials    -DBOOST_DISABLE_ASSERTS          -c -Wno-ignored-attributes   -x c++ -o ../../ml/stanc3/fun.o ../../ml/stanc3/fun.hpp
In file included from stan/lib/stan_math/stan/math/prim/meta/is_eigen_matrix_base.hpp:6,
                 from stan/lib/stan_math/stan/math/prim/meta/is_eigen.hpp:5,
                 from stan/lib/stan_math/stan/math/prim/meta/base_type.hpp:6,
                 from stan/lib/stan_math/stan/math/prim/meta/return_type.hpp:6,
                 from stan/lib/stan_math/stan/math/prim/meta/append_return_type.hpp:5,
                 from stan/lib/stan_math/stan/math/prim/meta.hpp:176,
                 from stan/lib/stan_math/stan/math/rev/core/accumulate_adjoints.hpp:4,
                 from stan/lib/stan_math/stan/math/rev/core.hpp:4,
                 from stan/lib/stan_math/stan/math/rev.hpp:8,
                 from stan/lib/stan_math/stan/math.hpp:19,
                 from stan/src/stan/model/model_header.hpp:4:
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp: In instantiation of ‘struct stan::is_base_pointer_convertible<Eigen::EigenBase, double (&)(const int&, std::basic_ostream<char>*)>’:
stan/lib/stan_math/stan/math/prim/meta/is_var_matrix.hpp:18:8:   recursively required by substitution of ‘template<class T> struct stan::value_type<T, typename std::enable_if<stan::is_eigen<T>::value, void>::type> [with T = double (&)(const int&, std::basic_ostream<char>*)]’
stan/lib/stan_math/stan/math/prim/meta/is_var_matrix.hpp:18:8:   required from ‘struct stan::is_var_matrix<double (&)(const int&, std::basic_ostream<char>*)>’
stan/lib/stan_math/stan/math/prim/meta/conjunction.hpp:17:8:   required from ‘struct stan::math::conjunction<stan::is_var_matrix<double (&)(const int&, std::basic_ostream<char, std::char_traits<char> >*)>, stan::is_eigen<double (&)(const int&, std::basic_ostream<char, std::char_traits<char> >*)> >’
stan/lib/stan_math/stan/math/prim/meta/require_helpers.hpp:63:24:   required by substitution of ‘template<class ... Checks> using require_any_not_t = std::enable_if_t<(! stan::math::conjunction<T>::value)> [with Checks = {stan::is_var_matrix<double (&)(const int&, std::basic_ostream<char, std::char_traits<char> >*)>, stan::is_eigen<double (&)(const int&, std::basic_ostream<char, std::char_traits<char> >*)>}]’
stan/src/stan/model/indexing/access_helpers.hpp:43:65:   required by substitution of ‘template<class T1, class T2, stan::require_any_not_t<stan::is_var_matrix<Container>, stan::is_eigen<T_actual> >* <anonymous> > void stan::model::internal::assign_impl(T1&&, T2&&) [with T1 = double (&)(const int&, std::basic_ostream<char>*); T2 = double (&)(const int&, std::basic_ostream<char>*); stan::require_any_not_t<stan::is_var_matrix<Container>, stan::is_eigen<T_actual> >* <anonymous> = <missing>]’
stan/src/stan/model/indexing/assign.hpp:57:24:   required from ‘void stan::model::assign(T&&, U&&, const char*) [with T = double (&)(const int&, std::basic_ostream<char>*); U = double (&)(const int&, std::basic_ostream<char>*); stan::require_t<std::is_assignable<typename std::decay<_Tp>::type&, typename std::decay<_Func>::type> >* <anonymous> = 0]’
../../ml/stanc3/fun.hpp:73:61:   required from here
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:29:17: error: no matching function for call to ‘stan::is_base_pointer_convertible<Eigen::EigenBase, double (&)(const int&, std::basic_ostream<char>*)>::f(double (*)(const int&, std::basic_ostream<char>*))’
   29 |     = decltype(f(std::declval<std::remove_reference_t<Derived> *>()))::value
      |                ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:24:26: note: candidate: ‘static std::false_type stan::is_base_pointer_convertible<Base, Derived>::f(const void*) [with Base = Eigen::EigenBase; Derived = double (&)(const int&, std::basic_ostream<char>*); std::false_type = std::integral_constant<bool, false>]’ <near match>
   24 |   static std::false_type f(const void *);
      |                          ^
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:24:26: note:   conversion of argument 1 would be ill-formed:
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:29:17: error: invalid conversion from ‘double (*)(const int&, std::basic_ostream<char>*)’ to ‘const void*’ [-fpermissive]
   29 |     = decltype(f(std::declval<std::remove_reference_t<Derived> *>()))::value
      |                ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                 |
      |                 double (*)(const int&, std::basic_ostream<char>*)
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:26:25: note: candidate: ‘template<class OtherDerived> static std::true_type stan::is_base_pointer_convertible<Base, Derived>::f(const Base<OtherDerived>*) [with OtherDerived = OtherDerived; Base = Eigen::EigenBase; Derived = double (&)(const int&, std::basic_ostream<char>*)]’
   26 |   static std::true_type f(const Base<OtherDerived> *);
      |                         ^
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:26:25: note:   template argument deduction/substitution failed:
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:29:17: note:   mismatched types ‘const Eigen::EigenBase<Derived>’ and ‘double(const int&, std::basic_ostream<char>*)’
   29 |     = decltype(f(std::declval<std::remove_reference_t<Derived> *>()))::value
      |                ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make: *** [make/program:58: ../../ml/stanc3/fun] Error 1
make: Leaving directory '/home/brian/Dev/cpp/cmdstan'

Expected Behavior:

At the moment I would expect this to be an error. After something like #742 or lambdas, I would expect the C++ generated to compile.

This is probably a low-priority issue as the cases it comes up are obviously pathological, I just wanted to document it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working robustness
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant