Spaceship operator oddity with optional

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Spaceship operator oddity with optional

shirley breuer via cfe-dev
Hi,

I just bumped into this mysterious behavior with the spaceship operator over
optional:

struct expr {
  std::strong_ordering operator<=>(const expr &rhs) const;
  //bool operator==(const expr &rhs) const;
};

int f() {
  return std::is_eq(std::optional<expr>() <=> std::optional<expr>());
  //return std::optional<expr>() == std::optional<expr>();
}

Function f() returns 0 both on gcc & clang trunk
(https://gcc.godbolt.org/z/fv85eP).
However, if you uncomment the operator==() line, the function starts
returning 1.

The documentation of
https://en.cppreference.com/w/cpp/utility/optional/operator_cmp just says:
    7) If bool(lhs) && bool(rhs) is true returns *x <=> *y
      Otherwise, returns bool(lhs) <=> bool(rhs)

So no word about operator=='s existence.
Is this a bug in both clang & gcc or just some unobvious 3-way comparison
rule I'm not aware?

Thanks,
Nuno

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Spaceship operator oddity with optional

shirley breuer via cfe-dev
On Tue, Jan 26, 2021 at 8:58 AM Nuno Lopes via cfe-dev <[hidden email]> wrote:

I just bumped into this mysterious behavior with the spaceship operator over
optional:

struct expr {
  std::strong_ordering operator<=>(const expr &rhs) const;
  //bool operator==(const expr &rhs) const;
};

int f() {
  return std::is_eq(std::optional<expr>() <=> std::optional<expr>());
  //return std::optional<expr>() == std::optional<expr>();
}

Function f() returns 0 both on gcc & clang trunk
(https://gcc.godbolt.org/z/fv85eP).
However, if you uncomment the operator==() line, the function starts
returning 1.

The documentation of
https://en.cppreference.com/w/cpp/utility/optional/operator_cmp just says:
    7) If bool(lhs) && bool(rhs) is true returns *x <=> *y
      Otherwise, returns bool(lhs) <=> bool(rhs)

So no word about operator=='s existence.
Is this a bug in both clang & gcc or just some unobvious 3-way comparison
rule I'm not aware?

I haven't dug deep, but based on your description it's an issue with GNU libstdc++, not an issue with either of the compilers themselves.
Neither libc++ nor Microsoft STL support C++20 optional::operator<=> yet; libstdc++ is the only library vendor who's tried to implement it, and if their implementation doesn't match your expectations, then my guess is that it's a bug in their implementation. (Or, perhaps, a bug in your expectations — but I give it more than 50/50 it's an implementation bug in libstdc++. The details of operator-spaceship have changed many times in the past 3 years and maybe GNU libstdc++ is implementing some older version.)

My guess is that libstdc++ std::optional hasn't caught up to the compiler changes from

HTH,
Arthur


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Spaceship operator oddity with optional

shirley breuer via cfe-dev

Thank you!

I will investigate your lead and report the bug to libstdc++. Ive been hitting quite a few bugs in synthesized <=> operators lately..

 

Thanks,

Nuno

 

From: Arthur O'Dwyer <[hidden email]>
Sent: 26 January 2021 16:14
To: Nuno Lopes <[hidden email]>
Cc: Clang Dev <[hidden email]>
Subject: Re: [cfe-dev] Spaceship operator oddity with optional

 

On Tue, Jan 26, 2021 at 8:58 AM Nuno Lopes via cfe-dev <[hidden email]> wrote:


I just bumped into this mysterious behavior with the spaceship operator over
optional:

struct expr {
  std::strong_ordering operator<=>(const expr &rhs) const;
  //bool operator==(const expr &rhs) const;
};

int f() {
  return std::is_eq(std::optional<expr>() <=> std::optional<expr>());
  //return std::optional<expr>() == std::optional<expr>();
}

Function f() returns 0 both on gcc & clang trunk
(https://gcc.godbolt.org/z/fv85eP).
However, if you uncomment the operator==() line, the function starts
returning 1.

The documentation of
https://en.cppreference.com/w/cpp/utility/optional/operator_cmp just says:
    7) If bool(lhs) && bool(rhs) is true returns *x <=> *y
      Otherwise, returns bool(lhs) <=> bool(rhs)

So no word about operator=='s existence.
Is this a bug in both clang & gcc or just some unobvious 3-way comparison
rule I'm not aware?

 

I haven't dug deep, but based on your description it's an issue with GNU libstdc++, not an issue with either of the compilers themselves.

Neither libc++ nor Microsoft STL support C++20 optional::operator<=> yet; libstdc++ is the only library vendor who's tried to implement it, and if their implementation doesn't match your expectations, then my guess is that it's a bug in their implementation. (Or, perhaps, a bug in your expectations — but I give it more than 50/50 it's an implementation bug in libstdc++. The details of operator-spaceship have changed many times in the past 3 years and maybe GNU libstdc++ is implementing some older version.)

 

My guess is that libstdc++ std::optional hasn't caught up to the compiler changes from

 

HTH,

Arthur


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev