Skip to content

[Aws::Crt::Optional] avoid std::aligned_storage #462

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

Merged
merged 1 commit into from
Feb 2, 2023
Merged

[Aws::Crt::Optional] avoid std::aligned_storage #462

merged 1 commit into from
Feb 2, 2023

Conversation

kedartal
Copy link
Contributor

Description of changes:

Checks if std::optional is available, and if so, alias Aws::Crt::Optional<T> to std::optional<T>.
Also, fix a missing #include <type_traits> when not aliasing, for std::aligned_storage.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@kedartal
Copy link
Contributor Author

Context: std::aligned_storage is deprecated in c++23 (cplusplus/draft#5282). Instead of awkwardly working around it (ignoring deprecated warnings, setting _LIBCPP_DISABLE_DEPRECATION_WARNINGS...) or re-implementing Aws::Crt::Optional, using the standard implementation seems simpler moving forward.

Please note that std::optional is not functionally identical to the Aws::Crt::Optional implementation in c++20 and above -- constexpr and monadic operations were added. Such functionality can be used conditionally by testing the standard __cpp_lib_optional macro (https://en.cppreference.com/w/cpp/feature_test). I couldn't think of a reason why this would break any existing code, but naturally I might be missing something.

@graebm
Copy link
Contributor

graebm commented Jan 31, 2023

We can't simply alias the two types like this.

We used to do that, but later realized it didn't work, and removed the aliasing here: 402d222

using Optional = std::optional; seems like the smart thing to do if your application is c++17. Except we always compile aws-crt-cpp with c++11, so the library's compiled code uses the ABI of our custom Aws::Crt::Optional class. And if a c++17 application includes that header, it’s like “oh yeah I’m c++17 so the ABI of this thing is std::optional”

Solution is: always define our own custom Optional class, even if user’s application is c++17. They’re just different classes, each with its own ABI, even if they have the same API

@graebm
Copy link
Contributor

graebm commented Jan 31, 2023

Can we get rid of the deprecation warnings by using alignas instead of aligned_storage, as suggested on this stackoverflow post?

Or we might be able to just remove the alignment stuff. I don't believe this library is putting anything in its custom Optional class that actually has alignment requirements

@kedartal
Copy link
Contributor Author

kedartal commented Jan 31, 2023

@graebm I see, though why is aws-crt-cpp always compiled with c++11? Anyway yes, alignas can work, or alternatively std::aligned_alloc (https://en.cppreference.com/w/c/memory/aligned_alloc). Any preferences?
Removing the alignment could break clients that use the class with their own types, but perhaps that's not a priority -- I'd definitely document it :)

@kedartal kedartal changed the title [Aws::Crt::Optional] alias to std::optional if available [Aws::Crt::Optional] avoid std::aligned_storage Jan 31, 2023
@kedartal
Copy link
Contributor Author

@graebm Something like that (just pushed)?

@graebm
Copy link
Contributor

graebm commented Jan 31, 2023

...alignas can work, or alternatively std::aligned_alloc (https://en.cppreference.com/w/c/memory/aligned_alloc). Any preferences?

std::aligned_alloc would perform an unnecessary allocation. Let's use alignas for in-place storage.

@graebm
Copy link
Contributor

graebm commented Jan 31, 2023

why is aws-crt-cpp always compiled with c++11?

If the library is used by multiple applications on the system (like if aws-crt-cpp ends up in a package manager, and is distributed precompiled), we want to be sure it's compatible with our minimum spec C++11.

@kedartal
Copy link
Contributor Author

kedartal commented Feb 1, 2023

@graebm you're right about std::aligned_alloc -- users could always make "fat" types cheap to move, this shouldn't be the responsibility of the optional container.
I don't think there would be any difference between std::array<char, sizeof(T)> and char[ sizeof(T) ] in this case, let's use whichever you like.
I wasn't aware that aws-crt-cpp is meant to guarantee ABI stability, makes sense; perhaps it's worth mentioning that in the documentation as a requirement, and maybe prepare for allowing ABI versioning (e.g, with linker scripts) since coroutines already landed and senders-receivers are just around the corner :)

std::aligned_storage is deprecated in c++23.

Co-authored-by: Michael Graeb <[email protected]>
@kedartal
Copy link
Contributor Author

kedartal commented Feb 2, 2023

@graebm please let me know what you think, I believe there are two options:

@kedartal
Copy link
Contributor Author

kedartal commented Feb 2, 2023

@graebm ... for the first option, something like alignas(T) unsigned char m_storage[ std::max( sizeof(T), sizeof(std::max_align_t) ];

@graebm
Copy link
Contributor

graebm commented Feb 2, 2023

I wasn't aware that aws-crt-cpp is meant to guarantee ABI stability

We don't guarantee it right now. But we aspire to someday

@graebm graebm merged commit f9ad934 into awslabs:main Feb 2, 2023
@kedartal kedartal deleted the use-std-optional branch February 2, 2023 17:43
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

Successfully merging this pull request may close these issues.

2 participants