graph-prototype
graph-prototype copied to clipboard
Compile-time constant `gr::RequiredSamples` causes compile errors
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.
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: