This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 110b. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2023-01-15


1687. Conversions of operands of built-in operators

Section: 12.2.2.3  [over.match.oper]     Status: C++14     Submitter: Richard Smith     Date: 2013-05-17

[Moved to DR at the February, 2014 meeting.]

Consider an example like:

  struct Y {
    operator int*();
  };

  extern int *p;
  int *a = p + 100.0;   // #1
  int *b = Y() + 100.0; // #2

#1 is ill-formed because it violates the requirement of 7.6.6 [expr.add] that the non-pointer operand have integral or enumeration type. It appears that #2 is well-formed, however, because 12.2.2.3 [over.match.oper] paragraph 7 says,

If a built-in candidate is selected by overload resolution, the operands are converted to the types of the corresponding parameters of the selected operation function. Then the operator is treated as the corresponding built-in operator and interpreted according to Clause 7 [expr].

In this case, the selected operation function is

  int *operator+(int *, std::ptrdiff_t)

100.0 is thus converted to std::ptrdiff_t before reaching 7.6.6 [expr.add].

This problem could be addressed by restricting the conversion to the class or enumeration operand rather than both operands.

Proposed resolution (January, 2014):

Change 12.2.2.3 [over.match.oper] paragraph 7 as follows:

If a built-in candidate is selected by overload resolution, the operands of class type are converted to the types of the corresponding parameters of the selected operation function, except that the second standard conversion sequence of a user-defined conversion sequence (12.2.4.2.3 [over.ics.user]) is not applied. Then the operator is treated as the corresponding built-in operator and interpreted according to Clause 7 [expr]. [Example:

  struct X {
    operator double();
  };

  struct Y {
    operator int*();
  };

  int *a = Y() + 100.0; // error: pointer arithmetic requires integral operand
  int *b = Y() + X();   // error: pointer arithmetic requires integral operand

end example]