-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
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
Core: Support c++20 compilation #89660
base: master
Are you sure you want to change the base?
Conversation
917f79d
to
2537226
Compare
2537226
to
57d8729
Compare
2b315bd
to
eea4fcd
Compare
655a1da
to
4e4d1f5
Compare
f3044b6
to
1b1499a
Compare
1b1499a
to
23a59f4
Compare
23a59f4
to
9ba6de0
Compare
7d0e2fd
to
67222b2
Compare
5f0769c
to
64f2c85
Compare
64f2c85
to
90c5451
Compare
18f8297
to
39863a7
Compare
39863a7
to
fc8019a
Compare
I think it's nice if someday we are choosing to bump up our standards to C++20. It will compile off-the-bat. |
fc8019a
to
b7001cd
Compare
It's possible that the C++20 minimum versions can be more lax than I originally expected, at least for our purposes, so I'm trying that out this rebase. Ideally, C++20 will be fully-functional on EDIT: Yep, seems good! Should make an eventual transition to C++20 much more reasonable |
b7001cd
to
c4e06a5
Compare
.github/workflows/linux_builds.yml
Outdated
@@ -72,6 +72,16 @@ jobs: | |||
# Skip 2GiB artifact speeding up action. | |||
artifact: false | |||
|
|||
- name: Editor w/ C++20 (target=editor, tests=yes, dev_build=yes, cpp_standard=20) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really want to add two builds though? It would take up much resources just for an edgecase that could be tested (not even needs to be tested regularly) by someone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, that's fair. I could just assign that value to an existing job instead, because it being accounted for in some form is important
c4e06a5
to
0877ee9
Compare
0877ee9
to
16f123b
Compare
I'm not sure I like the new INEQUALITY_OPERATOR macro, we don't have those for other operators. It feels out of place and a little confusing. It kind of smells like a workaround for something. |
• Technically c++23 as well, albeit to a *much* lesser extent because it's not officially released • You know what, I'll throw in c23 too, as a treat
16f123b
to
61a2d8f
Compare
The alternative is adding a bunch of cpp20 conditionals everywhere. It wouldn't be dealbreaking, but I wasn't sure if that was desired when starting off |
I think we should just either move to c++20, or not. I don't think that supporting c++17 while also using c++20 features is going to lead to a very pleasant codebase personally. |
To clarify, this isn't using C++20 features. This is only introducing fixes to make C++20 compilation work outright. Actually adding c++20 functionality wasn't within the original scope of the PR. I would love to migrate to C++20 fully. Concepts in particular would be the biggest draw, but |
I'll have to have a deeper look at that macro then, surely there's a way to do this is a way that's less jarring! Thanks for working on this by the way, I don't mean to sound super negative. |
The only two real alternative is giving all inequality operators class String {
...
bool operator==(const String &p_str) const; // Universal in C++17 & C++20
bool operator==(const char *p_str) const; // One-way in C++17, universal in C++20
...
}
// bool operator==(const String &p_str, const String &p_str); // "Ambiguous" error in C++17 & C++20
bool operator==(const char *p_cstr, const String &p_str); // Workaround in C++17, "ambiguous" error in C++20 The latter bit has to do with C++20 automatically rearranging the // RID, defaulted
#if __cplusplus < 202002L
_ALWAYS_INLINE_ bool operator==(const RID &p_rid) const {
return _id == p_rid._id;
}
_ALWAYS_INLINE_ bool operator<(const RID &p_rid) const {
return _id < p_rid._id;
}
_ALWAYS_INLINE_ bool operator<=(const RID &p_rid) const {
return _id <= p_rid._id;
}
_ALWAYS_INLINE_ bool operator>(const RID &p_rid) const {
return _id > p_rid._id;
}
_ALWAYS_INLINE_ bool operator>=(const RID &p_rid) const {
return _id >= p_rid._id;
}
_ALWAYS_INLINE_ bool operator!=(const RID &p_rid) const {
return _id != p_rid._id;
}
#else
_ALWAYS_INLINE_ std::strong_ordering operator<=>(const RID &p_rid) const = default; // Handles literally everything.
#endif
// Vector2, non-default
#if __cplusplus < 202002L
bool operator==(const Vector2 &p_other) const;
bool operator!=(const Vector2 &p_other) const;
bool operator<(const Vector2 &p_other) const { return x == p_other.x ? (y < p_other.y) : (x < p_other.x); }
bool operator>(const Vector2 &p_other) const { return x == p_other.x ? (y > p_other.y) : (x > p_other.x); }
bool operator<=(const Vector2 &p_other) const { return x == p_other.x ? (y <= p_other.y) : (x < p_other.x); }
bool operator>=(const Vector2 &p_other) const { return x == p_other.x ? (y >= p_other.y) : (x > p_other.x); }
#else
std::weak_ordering operator<=>(const Vector2 &p_other) const { // Non-default thanks to anonymous unions.
if (x <=> p_other.x != 0) {
return x <=> p_other.x;
}
return y <=> p_other.y;
}
bool operator==(const Vector2 &p_other) const { return *this <=> p_other == 0; } // Required because non-default.
// Explicit comparison operators *between* types often needed in C++20, so they can be scoped.
std::weak_ordering operator<=>(const Vector2i &p_other) const;
bool operator==(const Vector2i &p_other) const;
#endif Footnotes |
Well, I'm not the final arbiter of this decision. But I think my preference would go to a PR that just sets our minimum compiler to c++20, and makes these changes. I'd support that, I don't think there's any pressing reason at this time to support older compilers. Especially since we have the Godot toolchains for people who want to build on ancient Linux distros. Again, not my choice, but I am really grossed out by the macro approach, even though I agree with you that it is the "least bad" option. |
I'm all aboard the C++20 train. Maybe for 4.5? |
Adds a new
cpp_standard
experimental variable to SCons, to allow the user to choose which C++ standard to compile with. The choices are "17" and "20", defaulting to 17. In addition, this makes changes across the repo to allow compilation of c++20 to be possible in the first place, which primarily comes down to more operators to prevent ambiguous conversions. Currently, a c++20 build successfully compiles (withwerror=no
).Submitted as a draft, as while the equality operators are accounted for, there's still the ordering operators. Inequality operators could be handled with a wrapper, but ordering operators will be a bit more involved than that; ideally theEDIT: All warnings accounted for, no longer a draft! Ordering operators are outside the scope of this PR, now that I'm more familiar with just how much would need to change.<=>
operator will be used, so long as parity with the secondary operators is kept between 17 & 20. There's also the matter of making sure the other warnings are accounted for, which are largely secondary but still important so long as they don't negatively impact c++17 (which will remain the repo "default").EDIT: Added "support" for c++23 as well, albeit to a much lesser extent because its currently experimental.