Topic: Defect Report: bind1st/bind2nd type-safety
Author: ademkin@earthlink.net (Andrew Demkin)
Date: 29 Apr 02 12:59:19 GMT Raw View
[Moderator's note: this defect report has been
forwarded to the C++ committee. -moderator.]
--------
Problem:
--------
The definition of bind1st() {20.3.6.2 [lib.bind.1st]} 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 (5.2.3 [expr.type.conv]) is defined to be
semantically equivalent to an explicit cast expression (5.4 [expr.cast]),
which may (according to 5.4, paragraph 5) be interpreted as a
reinterpret_cast, thus masking the error.
-------------
Proposed fix:
-------------
The simplest and most localized change to prevent such errors is to require
bind1st() use a static_cast expression rather than the functional-style
conversion; that is, have bind1st() return:
binder1st<Operation>( op,
static_cast<typename Operation::first_argument_type>(x)).
A more agressive solution is to change the semantics of functional-style
conversions (5.2.3 [expr.type.conv]) to not permit a reinterpret_cast. For
contexts that require the semantics of reinterpret_cast, the language may
want to require the use of an explicit cast expression such as '(T) x' or
'reinterpret_cast<T>(x)' and limit the behavior of the functional notation
to match statically-checked and standard conversions (as defined by 5.2.9
[static.cast] and 4.10 [conv.ptr], etc.).
Although changing the semantics of functional-style conversions may seem
drastic and does have language-wide ramifications, it has the benefit of
better unifying the conversion rules for user defined types and built-in
types, which can be especially important for generic template programming.
------
Scope:
------
The problem and proposed change also apply to 20.3.6.4 [lib.bind.2nd].
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]