-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
AK: Allow Optional<T>
to be used in constant expressions
#4310
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
Hello! One or more of the commit messages in this PR do not match the Ladybird code submission policy, please check the |
Also take a look at SerenityOS/serenity#25880 |
05fb04b
to
be6f59f
Compare
Ladybird's |
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.
first look from my side
I'd like
@alimpfard @LucasChollet and @DanShaders
To also have a look
AK/Optional.h
Outdated
ALWAYS_INLINE Optional() = default; | ||
ALWAYS_INLINE constexpr Optional() | ||
{ | ||
construct_null_if_necessairy(); |
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.
As Cxbyte pointed out these are not needed, just add a = {}
to the null member
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.
That would unconditionally zero-fill the Optional
, which is not necessary at runtime since m_has_value
guards against uninitialized access.
AK/Optional.h
Outdated
ALWAYS_INLINE constexpr void construct_null_if_necessairy() | ||
{ | ||
// OPTIMIZATION: Only construct the `m_null` member when we are constant-evaluating. | ||
// Otherwise, this generates an unnecessairy zero-fill. | ||
#if defined(AK_COMPILER_GCC) || defined(HAS_ADDRESS_SANITIZER) | ||
// NOTE: GCCs -Wuninitialized warning ends up checking this as well. | ||
constexpr bool should_construct = true; | ||
#else | ||
constexpr bool should_construct = is_constant_evaluated(); | ||
#endif | ||
if (should_construct) | ||
m_null = {}; | ||
} |
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.
See above and CxBytes comments on the serenity PR
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.
I just re-confirmed in Compiler Explorer, initializing m_null
does indeed zero fill in cases where it shouldn't have to at -O3 optimizations on both Clang and GCC. I fixed the constexpr bool should_construct = is_constant_evaluated();
though, since that apparently always evaluates to true.
4bf654a
to
ea9052d
Compare
b6a4559
to
38376ae
Compare
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.
Looks vaguely fine, I didn't read the diff too carefully tho
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.
For all of these, if we already resolved one way or another on one of the SerenityOS PRs, I'll defer to that decision.
058ee0c
to
df1190f
Compare
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.
I think this is ready, but I'd like a second opinion from @alimpfard
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.
Just a couple notes, otherwise looks nice.
Much like `IsOneOfIgnoringCV`, some functions want to ignore both cv-qualifiers _and_ references. Add a template and concept for it.
This argument is removed (or rather, never added) by `-cc1`, which breaks any builds using GNU libc++, including CI.
Does exactly what it says on the tin.
This matches the behaviour of `std::is_scalar_v`
If a type is non-move constructible but move assignable, its container type may still be move assignable. Similairly, if a type is non-copy constructible but copy assignable, its container type may still be copy assignable.
df1190f
to
e8f7dde
Compare
This will change behaviour for moved-from `Optional<T>`s, since they will now no longer clear their value if `T` is trivial. However, a moved-from value should be considered to be in an unspecified state. Use `Optional<T>::clear` or `Optional<T>::release_value` instead.
e8f7dde
to
f6ac15b
Compare
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.
LGTM
Attempt 1: #2455
Related SerenityOS PR: SerenityOS/serenity#25740