graph-prototype icon indicating copy to clipboard operation
graph-prototype copied to clipboard

Compile-time constant `gr::RequiredSamples` causes compile errors

Open daniestevez opened this issue 1 year ago • 1 comments

I'm trying to use a compile-time constant gr::RequiredSamples in a port, but I'm getting some compiler errors. The following example is a minimal application that shows the problem: https://github.com/daniestevez/gr4-packet-modem/blob/main/examples/test_required_samples.cpp

It gives the following compiler errors:

/gr4-packet-modem/examples/test_required_samples.cpp:37:11: warning: unused variable 'block' [-Wunused-variable]
   37 |     auto& block = fg.emplaceBlock<TestRequiredSamples<int>>();
      |           ^~~~~
In file included from /gr4-packet-modem/examples/test_required_samples.cpp:1:
In file included from /gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/Block.hpp:15:
In file included from /gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/BlockTraits.hpp:6:
/gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/Port.hpp:984:51: error: binding reference of type 'std::size_t' (aka 'unsigned long') to value of type 'std::conditional_t<Required::kIsConst, const std::size_t, std::size_t>' (aka 'const unsigned long') drops 'const' qualifier
  984 |         : name(arg.name), priority(arg.priority), min_samples(arg.min_samples), max_samples(arg.max_samples), _accessor{ std::make_unique<wrapper<T, false>>(arg) } {}
      |                                                   ^           ~~~~~~~~~~~~~~~
/gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/Graph.hpp:330:38: note: in instantiation of function template specialization 'gr::DynamicPort::DynamicPort<gr::Port<int, gr::meta::fixed_string<char, 1UL - 1>{{}}, gr::PortType::STREAM, gr::PortDirection::OUTPUT, gr::RequiredSamples<1, 1, true>>>' requested here
  330 |                     where_.push_back(gr::DynamicPort(port, DynamicPort::non_owned_reference_tag{}));
      |                                      ^
/gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/Graph.hpp:339:25: note: in instantiation of function template specialization 'gr::BlockWrapper<TestRequiredSamples<int>>::createDynamicPortsLoader()::(anonymous class)::operator()()::(anonymous class)::operator()(std::vector<std::variant<gr::DynamicPort, gr::BlockModel::NamedPortCollection>> &, std::integral_constant<gr::PortDirection, gr::PortDirection::OUTPUT>, std::integral_constant<unsigned long, 0>, gr::Port<int, fixed_string<char, 4UL - 1>{"out"}, gr::PortType::STREAM, gr::PortDirection::OUTPUT, refl::descriptor::field_descriptor<TestRequiredSamples<int>, 1>, gr::RequiredSamples<1, 1, true>> &&)::(anonymous class)::operator()<gr::Port<int, gr::meta::fixed_string<char, 1UL - 1>{{}}, gr::PortType::STREAM, gr::PortDirection::OUTPUT, gr::RequiredSamples<1, 1, true>>, std::vector<std::variant<gr::DynamicPort, gr::BlockModel::NamedPortCollection>>>' requested here
  339 |                         processPort(where, port);
      |                         ^
/gr4-packet-modem/gnuradio4/meta/include/gnuradio-4.0/meta/typelist.hpp:344:10: note: in instantiation of function template specialization 'gr::BlockWrapper<TestRequiredSamples<int>>::createDynamicPortsLoader()::(anonymous class)::operator()()::(anonymous class)::operator()<std::vector<std::variant<gr::DynamicPort, gr::BlockModel::NamedPortCollection>>, std::integral_constant<gr::PortDirection, gr::PortDirection::OUTPUT>, std::integral_constant<unsigned long, 0>, gr::Port<int, fixed_string<char, 4UL - 1>{"out"}, gr::PortType::STREAM, gr::PortDirection::OUTPUT, refl::descriptor::field_descriptor<TestRequiredSamples<int>, 1>, gr::RequiredSamples<1, 1, true>>>' requested here
  344 |         (f(std::forward<LeadingArguments>(args)..., std::integral_constant<std::size_t, Is>{}, Ts{}), ...);
      |          ^
/gr4-packet-modem/gnuradio4/meta/include/gnuradio-4.0/meta/typelist.hpp:350:9: note: in instantiation of function template specialization 'gr::meta::typelist<gr::Port<int, fixed_string<char, 4UL - 1>{"out"}, gr::PortType::STREAM, gr::PortDirection::OUTPUT, refl::descriptor::field_descriptor<TestRequiredSamples<int>, 1>, gr::RequiredSamples<1, 1, true>>>::for_each_impl<(lambda at /gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/Graph.hpp:328:33) &, 0UL, std::vector<std::variant<gr::DynamicPort, gr::BlockModel::NamedPortCollection>> &, std::integral_constant<gr::PortDirection, gr::PortDirection::OUTPUT>>' requested here
  350 |         for_each_impl(std::forward<F>(f), std::make_index_sequence<sizeof...(Ts)>{}, std::forward<LeadingArguments>(args)...);
      |         ^
/gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/Graph.hpp:364:52: note: in instantiation of function template specialization 'gr::meta::typelist<gr::Port<int, fixed_string<char, 4UL - 1>{"out"}, gr::PortType::STREAM, gr::PortDirection::OUTPUT, refl::descriptor::field_descriptor<TestRequiredSamples<int>, 1>, gr::RequiredSamples<1, 1, true>>>::for_each<(lambda at /gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/Graph.hpp:328:33) &, std::vector<std::variant<gr::DynamicPort, gr::BlockModel::NamedPortCollection>> &, std::integral_constant<gr::PortDirection, gr::PortDirection::OUTPUT>>' requested here
  364 |             traits::block::all_output_ports<Node>::for_each(registerPort, _dynamicOutputPorts, std::integral_constant<PortDirection, PortDirection::OUTPUT>{});
      |                                                    ^
/gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/Graph.hpp:323:38: note: while substituting into a lambda expression here
  323 |         _dynamicPortsLoader = [this] {
      |                                      ^
/gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/Graph.hpp:387:9: note: in instantiation of member function 'gr::BlockWrapper<TestRequiredSamples<int>>::createDynamicPortsLoader' requested here
  387 |         createDynamicPortsLoader();
      |         ^
/usr/lib/llvm-18/bin/../include/c++/v1/__memory/unique_ptr.h:597:30: note: in instantiation of member function 'gr::BlockWrapper<TestRequiredSamples<int>>::BlockWrapper' requested here
  597 |   return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...));
      |                              ^
In file included from /gr4-packet-modem/examples/test_required_samples.cpp:1:
In file included from /gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/Block.hpp:15:
In file included from /gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/BlockTraits.hpp:6:
/gr4-packet-modem/gnuradio4/core/include/gnuradio-4.0/Port.hpp:984:81: error: binding reference of type 'std::size_t' (aka 'unsigned long') to value of type 'std::conditional_t<Required::kIsConst, const std::size_t, std::size_t>' (aka 'const unsigned long') drops 'const' qualifier
  984 |         : name(arg.name), priority(arg.priority), min_samples(arg.min_samples), max_samples(arg.max_samples), _accessor{ std::make_unique<wrapper<T, false>>(arg) } {}
      |                                                                                 ^           ~~~~~~~~~~~~~~~
1 warning and 2 errors generated.

It seems that DynamicPort doesn't handle correctly the case when the min_samples and max_samples are compile-time constant.

daniestevez avatar May 17 '24 06:05 daniestevez

Yes, I also noticed this just yesterday, this is due to the compile time reflection generating the code that allows to update the setting with a coresponding tag. Shouldn't be too hard to add a check that only allows settings updates for non-const member fields, but I first wanted to finish my other issues first. Thanks for the report :+1:

wirew0rm avatar May 17 '24 07:05 wirew0rm