Skip to content

CXX-2625 Address sign conversion warnings for literal argument to make_unique<T[]>() #1044

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
Oct 23, 2023

Conversation

eramongodb
Copy link
Contributor

Address the following warning:

warning: implicit conversion changes signedness: 'int' to 'std::size_t' (aka 'unsigned long') [-Wsign-conversion]
    return Impl::make(std::true_type{}, std::forward<Args>(args)...);
           ~~~~                         ^~~~~~~~~~~~~~~~~~~~~~~~
note: in instantiation of function template specialization 'bsoncxx::stdx::make_unique<int[], int, bsoncxx::stdx::detail::make_unique_impl<int[]>, std::unique_ptr<int[]>>' requested here
    auto ptr = bsoncxx::stdx::make_unique<int[]>(3);
                              ^
1 warning generated.

given the following code:

auto ptr = bsoncxx::stdx::make_unique<int[]>(3);

for conformance with specification that states there should be a separate overload for the unbounded array case with an explicit single std::size_t parameter which integral literals that are representable by std::size_t should be able to initialize without triggering a warning.

Proposed changes make use of the std::enable_if_t<cond, decltype(expr, void())>* = nullptr pattern to define multiple SFINAE templates without conflicts using both a boolean condition cond and an expression validity check expr. Note: uniqueness of both the condition and the expression is encoded in the specialization of std::enable_if as a non-type template parameter, avoiding the possibility of "template parameter redefines default argument" errors that is often encountered when using the typename = ... pattern for multiple overloads.

The std::enable_if<...>* = nullptr pattern can be changed to std::enable_if<...> = 0 if preferable. (Makes no singificant difference; just a style choice.)

Examples of warnings and errors on expression validity failure with proposed changes:

auto ptr = bsoncxx::stdx::make_unique<int[]>(3);  // No warnings.
auto ptr = bsoncxx::stdx::make_unique<int[]>(3u); // No warnings.
warning: implicit conversion changes signedness: 'int' to 'std::size_t' (aka 'unsigned long') [-Wsign-conversion]
    return Impl::make(std::true_type{}, std::forward<Args>(args)...);
           ~~~~                         ^~~~~~~~~~~~~~~~~~~~~~~~
note: in instantiation of function template specialization 'bsoncxx::stdx::make_unique<int[], int, bsoncxx::stdx::detail::make_unique_impl<int[]>, std::unique_ptr<int[]>>' requested here
    auto ptr = bsoncxx::stdx::make_unique<int[]>(-1);
                              ^
error: no matching function for call to 'make_unique'
    auto ptr = bsoncxx::stdx::make_unique<int[3]>(3);
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: candidate template ignored: substitution failure [with T = int[3], Args = <int>, Impl = bsoncxx::stdx::detail::make_unique_impl<int[3]>]: no member named 'make' in 'bsoncxx::stdx::detail::make_unique_impl<int[3]>'
std::unique_ptr<T> make_unique(Args&&... args) {
                   ^

@eramongodb eramongodb self-assigned this Oct 20, 2023
Copy link
Contributor

@vector-of-bool vector-of-bool left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good find. I hadn't realized this.

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