362. bind1st/bind2nd type safety

Section: 99 [depr.lib.binders] Status: CD1 Submitter: Andrew Demkin Opened: 2002-04-26 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [depr.lib.binders].

View all issues with CD1 status.

Discussion:

The definition of bind1st() (99 [depr.lib.binders]) can result in the construction of an unsafe binding between incompatible pointer types. For example, given a function whose first parameter type is 'pointer to T', it's possible without error to bind an argument of type 'pointer to U' when U does not derive from T:

   foo(T*, int);

   struct T {};
   struct U {};

   U u;

   int* p;
   int* q;

   for_each(p, q, bind1st(ptr_fun(foo), &u));    // unsafe binding

The definition of bind1st() includes a functional-style conversion to map its argument to the expected argument type of the bound function (see below):

  typename Operation::first_argument_type(x)

A functional-style conversion (99 [depr.lib.binders]) is defined to be semantically equivalent to an explicit cast expression (99 [depr.lib.binders]), which may (according to 5.4, paragraph 5) be interpreted as a reinterpret_cast, thus masking the error.

The problem and proposed change also apply to 99 [depr.lib.binders].

Proposed resolution:

Add this sentence to the end of 99 [depr.lib.binders]/1: "Binders bind1st and bind2nd are deprecated in favor of std::tr1::bind."

(Notes to editor: (1) when and if tr1::bind is incorporated into the standard, "std::tr1::bind" should be changed to "std::bind". (2) 20.5.6 should probably be moved to Annex D.

Rationale:

There is no point in fixing bind1st and bind2nd. tr1::bind is a superior solution. It solves this problem and others.