Skip to content

Unexpected results when setting a parameter value with a string returned from a lambda #116

@spchamp

Description

@spchamp

After storing a string value to an argument pack for a given parameter keyword, when the string value is provided via std::invoke of a lambda expression, then the string retrieved for that same keyword may represent an unexpected value.

There's a minimal example of the issue, available at the Compiler Explorer.

The parameter value is being set with the following function:

template <typename Tag, typename Func, typename Args>
  requires (!detail::argument_pack_contains<Args, param::keyword<Tag>>::value)
inline auto ensure_param_default(Args const& args, param::keyword<Tag> const& kw,
                                 Func&& func) {
  return param::compose((kw = std::invoke(func, args)), args);
}

When this is called like as follows, the resulting string value may have a size far exceeding 3:

BOOST_PARAMETER_NAME((_arg1, tags) test_arg1)
BOOST_PARAMETER_NAME((_arg2, tags) test_arg2)
 
// [...]

int main() {
  auto const args_in = (_arg2 = 31213);

  auto const args_out =
        ensure_param_default(args_in, _arg1, [](auto const&) -> std::string {
          return "ABC";
        });

   // [...]

  std::string const& s_out = args_out[_arg1];

  // [...]
}

With the example at the Compiler Explorer, when this is compiled locally, I'm seeing results such as the following. The mangled string is varying in each call.

-- failed : string test
s_out.size() := 140722429578688
s_out.data() := �9
-- passed : int test

The Compiler Explorer may not display the unexpected character data, in this case.

I'd discovered this when trying to produce a function that would return an argument pack, after providing any system-specified default values for certain keywords when not provided in the user args. This was for a purpose of applying the resulting argument pack, when initializing a Boost.Log console frontend. I'm certain that there may be other ways to approach this, using Boost.Parameter.

With the present example, could it be a matter of how the string is being provided for the parameter keyword?

I'm afraid that I've not been able to reproduce a failing test for integer storage, using a similar approach The example at the compiler explorer might at least illustrate the failing characters/string test.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions