-
-
Notifications
You must be signed in to change notification settings - Fork 23.9k
Core: Support c++20 compilation #89660
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
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
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
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++20The 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;
#endifFootnotes |
|
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? |
|
Superseded by #100749 |
Adds a new
cpp_standardexperimental 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.