Boost logo

Boost :

From: Fred Bertsch (fred.bertsch_at_[hidden])
Date: 2006-04-12 16:51:03


There are cases where boost::parameter can translate its arguments to
the wrong arguments at the function implementation side. I'm hoping
that I'm doing something wrong, but it seems like a problem with the
parameter library.

The parameter library suggests creating global variables named with
the names of the arguments to your function. If you have an inner
scope at the calling site with a variable with the same name, things
don't work. I'm okay if this simply results in a compiler error, but
in some fairly simple cases, it can correctly compile to the wrong
call to the implemented function.

Here's an example:

void FooImpl( int x, int y ) {
  // Gets x = 8, y = 14. We wanted x = 12, y = 8.
}

BOOST_PARAMETER_KEYWORD( tags, x )
BOOST_PARAMETER_KEYWORD( tags, y )

typedef boost::parameter::parameters< tags::x, tags::y > FooParams;

template< typename ArgumentPack >
void FooImpl( ArgumentPack const& args ) {
  typename boost::parameter::binding<
      ArgumentPack, tags::x, int >::type xx = args[ x | 12 ];
  typename boost::parameter::binding<
      ArgumentPack, tags::y, int >::type yy = args[ y | 14 ];
  FooImpl( xx, yy );
}

// Some overloads are left out. This shouldn't matter.
template< typename T0 >
void Foo( T0 const& a0 ) {
  FooImpl( FooParams()( a0 ) );
}

void Bar( int y ) {
  ...
  Foo( y = 8 );
  ...
}

Notice that Bar has an argument with the same name as one of the
global variables declared with BOOST_PARAMETER_KEYWORD.

I can't think of a general solution to this problem. It might be
better to use the call syntax "Foo( y( 8 ) );" instead because
overloaded function call operators are less common than assignment
operators. This does not remove the danger, however; it only disguises
it better. Another solution might be to put all of the global
variables in their own named namespace so that one has to qualify
their use. E.g.: "Foo( arg::y = 8 );". Some other naming convention
might also mitigate the problem.

Note that my example looks fairly artificial because I've simplified
it so much, but it's not as unlikely as it looks. The global variable
is called something that meaningfully describes the argument. It is
not so unlikely for a caller to have a variable with the same purpose
in the context of the call, and it is not unlikely for that to have
the same name.

Hopefully I'm missing something important here. Please correct my
misunderstanding if that's true.

-Fred Bertsch


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk