Skip to content

Conversation

sfod
Copy link
Contributor

@sfod sfod commented Aug 11, 2025

Issue #, if available:

This PR resolves two issues with Crt::Variant.

Issue 1. Compilation error on Windows platform when an underlying type has special function member(s) deleted

When building shared libraries on Windows platform, we add __declspec(dllexport) attribute to class definitions. MS docs say the following:

When you declare a class dllexport, all its member functions and static data members are exported.

This means that compiler will try to generate special function members whenever possible because it doesn't know which members a user of a .dll will use. Whether the compiler generates a special member function depends on 1) if base classes have this special member function and 2) member fields have this special member function.

The issue with Crt::Variant is that all its special member functions are defined as if the underlying types always support copying and moving (for copy constructor example, see 1 and 2). Consequently, the compiler attempts to generate all special member functions for the user class, resulting in compilation error:

77>C:\a\aws-crt-cpp\aws-crt-cpp\aws-crt-cpp\include\aws\crt\Variant.h(484,41): error C2280:
's_VariantBasicOperandsCompile::MoveOnlyTest::MoveOnlyTest(
        const s_VariantBasicOperandsCompile::MoveOnlyTest &)':
attempting to reference a deleted function
[C:\a\aws-crt-cpp\aws-crt-cpp\aws-crt-cpp\build\aws-crt-cpp\tests\aws-crt-cpp-tests.vcxproj]

See a CI run where new tests failed and a godbolt snippet demonstrating the issue.

Issue 2. Compilation error on old gcc compilers when a user class constructor has noexcept specifier

Constructors in Crt::Variant doesn't have noexcept specifier. When a user class tries to add noexcept, it causes compilation error on older gcc compilers:

<source>:11:5: note: 'Bar::Bar() noexcept' is implicitly deleted because its exception-specification
does not match the implicit exception-specification ''

This stopped to be an error in gcc 10.

Description of changes:

  1. The first problem can be resolved by removing user-defined special members from Crt::Variant. Move all implementation details into VariantImpl, with Variant members delegating work to VariantImpl.
    The special members in Variant will be either defaulted or deleted based on the underlying type traits. This is achieved by inheriting from auxiliary classes that have appropriately defaulted or deleted special members.

    This issue can also be resolved by explicitly deleting special members in user classes. However, this approach is inconvenient for Crt::Variant users. Therefore, if cleaner solution exists, it should be implemented instead.

  2. Add noexcept specifier to the Crt::Variant constructors based on the underlying type traits.

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

@sfod sfod marked this pull request as ready for review August 15, 2025 18:56
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