Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[class.spaceship]/3 operation order is unclear #2748

Closed
CaseyCarter opened this issue Mar 6, 2019 · 4 comments
Closed

[class.spaceship]/3 operation order is unclear #2748

CaseyCarter opened this issue Mar 6, 2019 · 4 comments
Assignees

Comments

@CaseyCarter
Copy link
Contributor

The subject paragraph:

The return value V of type R of the defaulted three-way comparison operator function with parameters x and y of the same type is determined by comparing corresponding elements x_i and y_i in the expanded lists of subobjects for x and y until the first index i where x_i <=> y_i yields a result value v_i where v_i != 0, contextually converted to bool, yields true; V is v_i converted to R. If no such index exists, V is std::strong_ordering::equal converted to R.

is clear that corresponding elements are compared, and that the process of comparison must terminate, but specifies neither the order in which indices within the list of subobjects are chosen nor that said sequence of chosen indices contains no duplicates. It's almost certainly the intent that corresponding pairs of elements are compared in order of increasing subscript, but that doesn't seem to be mandated.

#2729 adds similar wording elsewhere with the same issue. Could we clarify these editorially, or does this need a core issue?

@jensmaurer
Copy link
Member

@zygoloid?

@zygoloid
Copy link
Member

zygoloid commented Mar 7, 2019

"comparing [...] in the [...] list [...] until the first index [...]" seems pretty clear to me that the intent is that you walk the elements of the list in the order in which they appear in the list. That said, I do agree that it's possible to read this as pulling indices from an unspecified set of indices in an unspecified order.

Adding an "(in increasing index order)" or similar seems sufficiently far into "clarification of obvious intent" category that I think I'd be comfortable adding that editorially. Would that satisfy your concern? (Note that due to /1's "It is unspecified whether virtual base class subobjects are compared more than once.", we don't actually want to say that each index is considered exactly once.)

@CaseyCarter
Copy link
Contributor Author

CaseyCarter commented Mar 7, 2019

Adding an "(in increasing index order)" or similar seems sufficiently far into "clarification of obvious intent" category that I think I'd be comfortable adding that editorially. Would that satisfy your concern?

Yes, that was my suggestion in #2729 (comment) - Jens wanted you to approve that such a clarification would be editorial.

(Note that due to /1's "It is unspecified whether virtual base class subobjects are compared more than once.", we don't actually want to say that each index is considered exactly once.)

The implication of the "list of subobjects" wording is that virtual base class subobjects may appear more than once in the list of subobjects. If that is the case each appearance would have a distinct index, so considering each index only once would not contradict that sentence.

@zygoloid
Copy link
Member

The implication of the "list of subobjects" wording is that virtual base class subobjects may appear more than once in the list of subobjects.

That's not actually the case we care about, and it's not possible, because only direct base classes are in the list, and a virtual base class can be a direct base class at most once.

considering each index only once would not contradict that sentence.

The problem is not that we'd be restricted to consider each index at most once, the problem is that we'd be restricted to consider each index at least once. Consider:

struct A { friend std::strong_ordering operator<=>(A, A); };
struct B : virtual A {
  friend auto operator<=>(const B&, const B&) = default;
};
struct C : virtual A {
  friend auto operator<=>(const B&, const B&) = default;
  int n;
};
struct D : B, C {
  friend auto operator<=>(const B&, const B&) = default;
};

The expanded list of subobjects for C is exactly [A, n]. But when we compare the C subobject of D, we might want to skip the first index in the list, because we already compared the A subobject when comparing the B subobject of D.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants