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

2024-12-19


2796. Function pointer conversions for relational operators

Section: 7.6.9  [expr.rel]     Status: DRWP     Submitter: Alisdair Meredith     Date: 2023-09-14

[Accepted as a DR at the November, 2023 meeting.]

Consider:

  void f() {}
  void g() noexcept {}

  void q() {
    bool b1 = f == g;     // OK
    bool b2 = f > g;      // error: different types
  }

For the equality operators, 7.6.10 [expr.eq] paragraph 3 specifies:

If at least one of the operands is a pointer, pointer conversions (7.3.12 [conv.ptr]), function pointer conversions (7.3.14 [conv.fctptr]), and qualification conversions (7.3.6 [conv.qual]) are performed on both operands to bring them to their composite pointer type (7.2.2 [expr.type]). Comparing pointers is defined as follows: ...

In contrast, the corresponding rule for relational operators in 7.6.9 [expr.rel] paragraph 3 specifies:

The usual arithmetic conversions (7.4 [expr.arith.conv]) are performed on operands of arithmetic or enumeration type. If both operands are pointers, pointer conversions (7.3.12 [conv.ptr]) and qualification conversions (7.3.6 [conv.qual]) are performed to bring them to their composite pointer type (7.2.2 [expr.type]). After conversions, the operands shall have the same type.

However, all major implementations accept the example.

Proposed resolution (approved by CWG 2023-10-06):

Change in 7.6.9 [expr.rel] paragraph 3 as follows:

The usual arithmetic conversions (7.4 [expr.arith.conv]) are performed on operands of arithmetic or enumeration type. If both operands are pointers, pointer conversions (7.3.12 [conv.ptr]), function pointer conversions (7.3.14 [conv.fctptr]), and qualification conversions (7.3.6 [conv.qual]) are performed to bring them to their composite pointer type (7.2.2 [expr.type]). After conversions, the operands shall have the same type.