Version
v2.0.250303.1
Summary
When I build my project for x86 (32-bit) with GCC 14.2.0 (MSYS2) in release mode, I get warnings dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] for winrt/base.h:
[...]winrt/base.h: In member function 'void winrt::impl::factory_cach
e_entry_base::clear()':
[...]winrt/base.h:6357:86: warning: dereferencing type-punned pointer
will break strict-aliasing rules [-Wstrict-aliasing]
6357 | int64_t const result = _InterlockedCompareExchange64((int64_t*)this, 0, *(int64_
t*)¤t_value);
[...]winrt/base.h:6359:28: warning: dereferencing type-punned pointer
will break strict-aliasing rules [-Wstrict-aliasing]
6359 | if (result == *(int64_t*)¤t_value)
[...]winrt/Windows.Foundation.h:173:43: warning: dereferencing type-p
unned pointer will break strict-aliasing rules [-Wstrict-aliasing]
173 | auto const _winrt_abi_type = *(abi_t<winrt::Windows::Foundation::IAsyncInfo>**)&
_winrt_casted_result;
[...]winrt/Windows.Foundation.h:2498:102: warning: dereferencing type
-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
2498 | (*this)(*reinterpret_cast<winrt::Windows::Foundation::IAsyncAction const*>(&asyn
cInfo), *reinterpret_cast<winrt::Windows::Foundation::AsyncStatus const*>(&asyncStatus));
The problematic code in base.h is:
#if defined _WIN64
#if defined(__GNUC__)
bool exchanged = __sync_bool_compare_and_swap((__int128*)this, *(__int128*)¤t_value, (__int128)0);
#else
bool exchanged = 1 == _InterlockedCompareExchange128((int64_t*)this, 0, 0, (int64_t*)¤t_value);
#endif
if (exchanged)
{
pointer_value->Release();
}
#else
int64_t const result = _InterlockedCompareExchange64((int64_t*)this, 0, *(int64_t*)¤t_value);
if (result == *(int64_t*)¤t_value)
{
pointer_value->Release();
}
#endif
Unlike base.h, the problematic code from Windows.Foundation.h doesn't seem to be architecture-specific (no _WIN64 and other macros).
Reproducible example
Save the following CMakeLists.txt and test.cpp to the same directory and run:
cmake -DCMAKE_BUILD_TYPE=Release -DWINRT_INCLUDE_DIR=<your-path-here> -B build
cmake --build build
CMakeLists.txt:
cmake_minimum_required(VERSION 3.22)
project(test)
add_executable(test test.cpp)
set_target_properties(
test PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED YES
CXX_EXTENSIONS NO)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(test PRIVATE -Wall -Wextra -pedantic)
endif()
target_include_directories(test PRIVATE "${WINRT_INCLUDE_DIR}")
target_link_libraries(test PRIVATE windowsapp)
test.cpp
#include <winrt/base.h>
#include <winrt/Windows.ApplicationModel.h>
#include <winrt/Windows.Foundation.h>
using namespace winrt::Windows::ApplicationModel;
int main()
{
auto startupTask = StartupTask::GetAsync(L"id").get();
}
The full output in my case is:
Details
[1/2] Building CXX object CMakeFiles/test.dir/test.cpp.obj
In file included from [...]/test/test.cpp:1:
[...]/include/winrt/base.h: In member function 'void winrt::impl::factory_cach
e_entry_base::clear()':
[...]/include/winrt/base.h:6357:86: warning: dereferencing type-punned pointer
will break strict-aliasing rules [-Wstrict-aliasing]
6357 | int64_t const result = _InterlockedCompareExchange64((int64_t*)this, 0, *(int64_
t*)¤t_value);
| ^~~~~~~
~~~~~~~~~~~~~~~~~
[...]/include/winrt/base.h:6359:28: warning: dereferencing type-punned pointer
will break strict-aliasing rules [-Wstrict-aliasing]
6359 | if (result == *(int64_t*)¤t_value)
| ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from [...]/test/test.cpp:3:
[...]/include/winrt/Windows.Foundation.h: In instantiation of 'auto winrt::imp
l::consume_Windows_Foundation_IAsyncInfo<D>::Status() const [with D = winrt::Windows::Foundation::IA
syncAction]':
[...]/include/winrt/Windows.Foundation.h:5133:35: required from 'auto winrt:
:impl::wait_get(const Async&) [with Async = winrt::Windows::Foundation::IAsyncAction]'
5133 | auto status = async.Status();
| ~~~~~~~~~~~~^~
[...]/include/winrt/Windows.Foundation.h:5261:23: required from here
5261 | impl::wait_get(static_cast<Windows::Foundation::IAsyncAction const&>(static_cast<D c
onst&>(*this)));
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~
[...]/include/winrt/Windows.Foundation.h:173:43: warning: dereferencing type-p
unned pointer will break strict-aliasing rules [-Wstrict-aliasing]
173 | auto const _winrt_abi_type = *(abi_t<winrt::Windows::Foundation::IAsyncInfo>**)&
_winrt_casted_result;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~
[...]/include/winrt/Windows.Foundation.h: In instantiation of 'auto winrt::imp
l::consume_Windows_Foundation_IAsyncInfo<D>::Status() const [with D = winrt::Windows::Foundation::IA
syncOperation<winrt::Windows::ApplicationModel::StartupTask>]':
[...]/include/winrt/Windows.Foundation.h:5133:35: required from 'auto winrt:
:impl::wait_get(const Async&) [with Async = winrt::Windows::Foundation::IAsyncOperation<winrt::Windo
ws::ApplicationModel::StartupTask>]'
5133 | auto status = async.Status();
| ~~~~~~~~~~~~^~
[...]/include/winrt/Windows.Foundation.h:5272:30: required from 'auto winrt:
:impl::consume_Windows_Foundation_IAsyncOperation<D, TResult>::get() const [with D = winrt::Windows:
:Foundation::IAsyncOperation<winrt::Windows::ApplicationModel::StartupTask>; TResult = winrt::Window
s::ApplicationModel::StartupTask]'
5272 | return impl::wait_get(static_cast<Windows::Foundation::IAsyncOperation<TResult> cons
t&>(static_cast<D const&>(*this)));
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[...]/test/test.cpp:11:56: required from here
11 | auto startupTask = StartupTask::GetAsync(L"id").get();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
[...]/include/winrt/Windows.Foundation.h:173:43: warning: dereferencing type-p
unned pointer will break strict-aliasing rules [-Wstrict-aliasing]
173 | auto const _winrt_abi_type = *(abi_t<winrt::Windows::Foundation::IAsyncInfo>**)&
_winrt_casted_result;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~
[...]/include/winrt/Windows.Foundation.h: In instantiation of 'int32_t winrt::
impl::delegate<winrt::Windows::Foundation::AsyncOperationCompletedHandler<TResult>, H>::Invoke(void*
, int32_t) [with H = winrt::impl::wait_for_completed<winrt::Windows::Foundation::IAsyncOperation<win
rt::Windows::ApplicationModel::StartupTask> >(const winrt::Windows::Foundation::IAsyncOperation<winr
t::Windows::ApplicationModel::StartupTask>&, uint32_t)::shared_type; TResult = winrt::Windows::Appli
cationModel::StartupTask; int32_t = int]':
[...]/include/winrt/Windows.Foundation.h:2529:27: required from here
2529 | int32_t __stdcall Invoke(void* asyncInfo, int32_t asyncStatus) noexcept final try
| ^~~~~~
[...]/include/winrt/Windows.Foundation.h:2531:114: warning: dereferencing type
-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
2531 | (*this)(*reinterpret_cast<winrt::Windows::Foundation::IAsyncOperation<TResult> c
onst*>(&asyncInfo), *reinterpret_cast<winrt::Windows::Foundation::AsyncStatus const*>(&asyncStatus))
;
|
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[...]/include/winrt/Windows.Foundation.h: In instantiation of 'int32_t winrt::
impl::delegate<winrt::Windows::Foundation::AsyncActionCompletedHandler, H>::Invoke(void*, int32_t) [
with H = winrt::impl::wait_for_completed<winrt::Windows::Foundation::IAsyncAction>(const winrt::Wind
ows::Foundation::IAsyncAction&, uint32_t)::shared_type; int32_t = int]':
[...]/include/winrt/Windows.Foundation.h:2496:27: required from here
2496 | int32_t __stdcall Invoke(void* asyncInfo, int32_t asyncStatus) noexcept final try
| ^~~~~~
[...]/include/winrt/Windows.Foundation.h:2498:102: warning: dereferencing type
-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
2498 | (*this)(*reinterpret_cast<winrt::Windows::Foundation::IAsyncAction const*>(&asyn
cInfo), *reinterpret_cast<winrt::Windows::Foundation::AsyncStatus const*>(&asyncStatus));
|
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[2/2] Linking CXX executable test.exe
Expected behavior
No response
Actual behavior
No response
Additional comments
I haven't tried compiling for 64 bit, but it's possible that similar warnings would appear in that case (in particular, the code in base.h intended for _WIN64 uses similar pointer dereferencing).
Version
v2.0.250303.1
Summary
When I build my project for x86 (32-bit) with GCC 14.2.0 (MSYS2) in release mode, I get warnings
dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]forwinrt/base.h:The problematic code in
base.his:Unlike
base.h, the problematic code fromWindows.Foundation.hdoesn't seem to be architecture-specific (no_WIN64and other macros).Reproducible example
Save the following CMakeLists.txt and test.cpp to the same directory and run:
CMakeLists.txt:
test.cpp
The full output in my case is:
Details
Expected behavior
No response
Actual behavior
No response
Additional comments
I haven't tried compiling for 64 bit, but it's possible that similar warnings would appear in that case (in particular, the code in
base.hintended for_WIN64uses similar pointer dereferencing).