C++ Logo


Advanced search

Is the result of comparing void pointers unspecified?

From: Paul Keir <Paul.Keir_at_[hidden]>
Date: Fri, 15 Oct 2021 10:52:36 +0000
Is the result of comparing pointers to cv void (e.g. void*) using the relational operators unspecified?

GCC, Clang and MSVC++ don't give a warning for code evaluated at runtime; and wouldn't need to. But, as part of a constant expression evaluation (constexpr), a comparison between void pointers, if it does lead to an unspecified result, *would* be expected to produce a compilation error. Currently, GCC and MSVC++ will accept the code below; Clang will reject it.

constexpr bool test()
  int arr[2]{};
  void *p1 = &arr[0];
  void *p2 = &arr[1];

  return p1 < p2;

int main(int argc, char *argv[])
  return test();

Section 7.7 (Constant expressions) [expr.const] states that *where the result is unspecified*, C++ excludes relational (and equality) operators, from the category of "core constant expression":

    An expression E is a core constant expression unless the evaluation of E, following the rules of the abstract machine ([intro.execution]), would evaluate one of the following:
    (5.23) a three-way comparison ([expr.spaceship]), relational ([expr.rel]), or equality ([expr.eq]) operator where the result is unspecified;

    From https://timsong-cpp.github.io/cppwp/n4861/expr.const#5.23

Which then leads to the question of whether the result *is* unspecified. Using *equality operators* on void pointers, is specified: Section 7.6.10 (Equality operators) [expr.eq] refers simply to "pointers", and void* is clearly there considered a pointer (see also [dcl.ptr]). Among other things, it then states that if two pointers both represent the same address, they compare equal.


Section 7.6.9 (Relational operators) [expr.rel], however, explains its semantics not in terms of "pointers", but only of "pointers to objects". It explains only how to compare "unequal pointers to objects".


Is void* a pointer to an object? Section 6.8.2 (Compound types) [basic.compound] states that the type of a pointer to cv void is called an "object pointer type", but immediately clarifies that it is *not* a pointer-to-object type.


So it seems that [expr.rel] does not specify the comparison of void pointers.

C++11 [expr.rel] had a clause about comparing void pointers, but this was removed in C++14 and since.

Concretely, should the code example above compile?

Please consider the environment and think before you print.

The University of the West of Scotland is a registered Scottish charity. Charity number SC002520.

This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender.

Please note that any views or opinions presented in this email are solely those of the author and do not necessarily represent those of the University of the West of Scotland.

As a public body, the University of the West of Scotland may be required to make available emails as well as other written forms of information as a result of a request made under the Freedom of Information (Scotland) Act 2002.

Received on 2021-10-15 05:52:43