简体   繁体   中英

c++ constexpr pointer and constexpr comparison

In the following code:

struct test{
    struct Data{};

    static constexpr const Data data1{};
    static constexpr const Data data2{};

    static constexpr const Data* pdata1 = &data1;
    static constexpr const Data* pdata2 = &data2;

    static constexpr const bool b1 = pdata1 == pdata2; // OK
    static constexpr const bool b2 = pdata1 != pdata2; // OK
    static constexpr const bool b3 = pdata1 <  pdata2; // ERROR: is not a constant expression
};

Compiler allow me to compare pointers with == and != . But < , > cause compiler error. Why so?

Comparing the addresses of two unrelated objects has an unspecified result

[expr.rel]

3 Comparing unequal pointers to objects is defined as follows:

  • If two pointers point to different elements of the same array, or to subobjects thereof, the pointer to the element with the higher subscript compares greater.

  • If two pointers point to different non-static data members of the same object, or to subobjects of such members, recursively, the pointer to the later declared member compares greater provided the two members have the same access control and provided their class is not a union.

  • Otherwise, neither pointer compares greater than the other.

4 If two operands p and q compare equal, p<=q and p>=q both yield true and p<q and p>q both yield false. Otherwise, if a pointer p compares greater than a pointer q, p>=q , p>q , q<=p , and q<p all yield true and p<=q , p<q , q>=p , and q>p all yield false. Otherwise, the result of each of the operators is unspecified.

And a relational expression with an unspecified result is explicitly forbidden from appearing in a constant expression

[expr.const]

2 An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:

  • ...
  • a relational or equality operator where the result is unspecified; or
  • ...

A compiler is required to issue a diagnostic when it encounters something forbidden in the evaluation of a constant expression. Hence you get an error.

Always bear in mind that the C++ standard defines things in terms of an abstract machine. Constant expressions are those which have well-defined semantics in that abstract machine, and so may be evaluated "at compile time" when all arguments are known. If something is unspecified in the abstract machine, it cannot produce a well-defined constant expression, so it's prohibited.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM