From 2c6cedf72728c3eca06284276703d50b31e84f4c Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 26 Oct 2025 16:35:47 +0800 Subject: [PATCH 1/2] Use aligned byte arrays as aligned buffers These buffers are not overaligned and should only be used for the purpose of storage providing, so it should be safe and simpler to use aligned `unsigned char` arrays. --- stl/inc/__msvc_threads_core.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/__msvc_threads_core.hpp b/stl/inc/__msvc_threads_core.hpp index 3bb43713a27..0340b3ddef8 100644 --- a/stl/inc/__msvc_threads_core.hpp +++ b/stl/inc/__msvc_threads_core.hpp @@ -7,7 +7,7 @@ #define __MSVC_THREADS_CORE_HPP #include #if _STL_COMPILER_PREPROCESSOR -#include +#include #pragma pack(push, _CRT_PACKING) #pragma warning(push, _STL_WARNING_LEVEL) @@ -43,7 +43,7 @@ struct _Mtx_internal_imp_t { int _Type{}; union { _Stl_critical_section _Critical_section{}; - _STD _Aligned_storage_t<_Critical_section_size, alignof(void*)> _Cs_storage; + alignas(void*) unsigned char _Cs_storage[_Critical_section_size]; }; long _Thread_id{}; int _Count{}; @@ -68,7 +68,7 @@ struct _Cnd_internal_imp_t { union { _Stl_condition_variable _Stl_cv{}; - _STD _Aligned_storage_t<_Cnd_internal_imp_size, alignof(void*)> _Cv_storage; + alignas(void*) unsigned char _Cv_storage[_Cnd_internal_imp_size]; }; }; #pragma warning(pop) From 48f86d2f4ee56cd37bb758bef659746e58e445fe Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 28 Oct 2025 14:24:22 -0700 Subject: [PATCH 2/2] Perma-workaround VSO-2616030. VSO-2616030 /clr /std:c++20 alignas emits bogus error C3645: 'main::::': __clrcall cannot be used on functions compiled to native code --- .../P0660R10_jthread_and_cv_any/test.cpp | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/std/tests/P0660R10_jthread_and_cv_any/test.cpp b/tests/std/tests/P0660R10_jthread_and_cv_any/test.cpp index e14d929d8fe..8f4a15c5428 100644 --- a/tests/std/tests/P0660R10_jthread_and_cv_any/test.cpp +++ b/tests/std/tests/P0660R10_jthread_and_cv_any/test.cpp @@ -147,30 +147,30 @@ int main() { assert(jthread::hardware_concurrency() == thread::hardware_concurrency()); { // first wait_until overload; without the cancellation this would deadlock - jthread worker([](stop_token token) { - mutex m; - condition_variable_any cv; + mutex m; + condition_variable_any cv; + jthread worker([&](stop_token token) { unique_lock lck{m}; assert(cv.wait(lck, move(token), [] { return false; }) == false); }); } - static constexpr auto forever = chrono::steady_clock::duration::max(); - static constexpr auto infinity = chrono::steady_clock::time_point::max(); + constexpr auto forever = chrono::steady_clock::duration::max(); + constexpr auto infinity = chrono::steady_clock::time_point::max(); { // ditto without the cancellation this would deadlock - jthread worker([](stop_token token) { - mutex m; - condition_variable_any cv; + mutex m; + condition_variable_any cv; + jthread worker([&](stop_token token) { unique_lock lck{m}; assert(cv.wait_until(lck, move(token), infinity, [] { return false; }) == false); }); } { // ditto without the cancellation this would deadlock - jthread worker([](stop_token token) { - mutex m; - condition_variable_any cv; + mutex m; + condition_variable_any cv; + jthread worker([&](stop_token token) { unique_lock lck{m}; assert(cv.wait_for(lck, move(token), forever, [] { return false; }) == false); });