c++clangllvmc++20coff

C++20 [[no_unique_address]] not working with clang's win32-coff target


While working with clang-13 in C++20, I noticed that the x86_64-pc-win32-coff cross-compile target seems to outright reject the [[no_unique_address]] attribute. This attribute is otherwise supported for other targets that I tested with.

Consider this minimal example:

struct bar {};

struct foo {
    [[no_unique_address]] bar b;
};

which, when compiled with -target=x86_64-pc-win32-coff, produces

<source>:4:7: warning: unknown attribute 'no_unique_address' ignored [-Wunknown-attributes]
    [[no_unique_address]] bar b;
      ^~~~~~~~~~~~~~~~~
1 warning generated.

Live Example

Is it a known issue for different targets to reject attributes, or is this a product of just the underlying cross-compile target? I know that MSVC historically did not do empty-base optimization and kept this for ABI compatibility; is this a product of that compatibility?

I suspect this is likely a bug in the target since it does not fully satisfy the C++20 spec, but I'm unsure of whether there is a pragmatic or known reason as to why this attribute is outright rejected, when other cross-compile targets seem to work without issue.


Solution

  • no_unique_address is something whose primary support has to be handled at the ABI level. Both the Itanium ABI and Microsoft's de-facto ABI (aka: whatever MSVC does) support no_unique_address... kinda.

    See, Microsoft is not at present willing to cause an ABI break. And since the attribute does nothing under a C++17 build, this would mean that compiling the same header for C++17 and C++20 could cause ODR violations.

    So instead, they're holding off on fully implementing the attribute. They have the code ready to go in the compiler (and you can even use the MSVC-specific attribute msvc::no_unique_address to get the same effect). But until they do an ABI break, they don't intend to support it.

    As such, Clang appears to be following Microsoft's lead on this.