Defect Report: bind1st/bind2nd type-safety

Defect Report: bind1st/bind2nd type-safety

Post by Andrew Demk » Tue, 30 Apr 2002 21:59:19



        [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 ]

[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]

 
 
 

1. defect in bind1st and bind2nd?

I'm not sure if this is a defect or intentional design, but neither
bin1st not bin2nd appear to be usable if the function object takes a
reference as one of its parameters - if it does then the binder tries
to create a reference to a reference which is not allowed (as far as I
know)

Any comments?

Thanks in advance,

John Maddock
http://ourworld.compuserve.com/homepages/John_Maddock/
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]

[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]

2. DVP9 Case from Devian

3. function objects and bind2nd / bind1st

4. push content from vb aspx page to browser

5. Getting around bind1st or bind2nd const ?

6. Looking for Gary Samad or Software Visions

7. Hi all - new to smalltalk [type services and type-safety]

8. search'ed documents have all the same date

9. Defect Report: Should new T and new T() initialise the memory differently for same type T

10. Defect Report: Restrictions on use of incomplete types not complete?

11. Defect Report: cv qualifiers on function types

12. Defect Report: Return Type of auto_ptr::operator=

13. Defect report: Explicit type conversion (functional n.)