I just found a bug in my code and I am pretty baffled that it could happen, since it is a simple signed/unsigned mismatch - which should not happen at all, because I am compiling with warning level 4, warnings as errors. So I tried to reproduce it, which is pretty simple:
#include <memory>
class MyClass {
public:
MyClass( unsigned ) {}
};
int main()
{
MyClass* rawP = new MyClass(-1); // issues a warning, as expected
auto uniqueP = std::make_unique<MyClass>(-1); // NO WARNING??!
// silence the compiler
rawP;
uniqueP;
return 0;
}
Now I'm asking myself: What's the reason of this? Is it a bug in VS, or is it a general shortcoming of std::make_unique? Is there any way to fix it? (Visual Studio 2015 Community Update 3)
You are seeing a combination of several effects.
main()is perfectly legitimate because themake_uniquetemplate instantiation matches the signed data type you feed it.make_uniquedoes not generate a warning because warnings are typically disabled inside system headers.make_unique.In more detail:
1. The template instantiation is actually legitimate.
A typical implementation of
std::make_uniquelooks like this (compare cppreference):In your case, as you call
std::make_unique<MyClass>(-1), the template is instantiated for a signed integer. Hence, you do not get a warning in your code because no unsigned/signed conversion happens.2. System headers typically disable warnings.
However, you could rightfully expect a warning from the
make_uniqueimplementation. After all, whennew T(...)is called with your signed parameter, a signed/unsigned conversion still happens. As a case in point, take the following program:When I compile this using GCC with
-Wsign-conversion, I get the warningSo the question is, why do you not get this warning for the
std::make_unique()implementation? The answer is essentially that the compiler silences these warnings for its system headers. For example, the GCC version of the<memory>header contains the pragmaAs soon as this pragma is present in a header file, the compiler no longer reports the warnings for everything inside that header. From the GCC documentation:
See also this SO post for more details. Presumably a similar approach is taken by Visual Studio's compiler (and as you wrote in your comment, the header temporarily reduces the warning level).
3. Looks like you are encountering a VisualStudio limitation.
In the case of VisualStudio, there is also something else at work. Note how the GCC warning above says that there may be a sign conversion problem (depending on what values users will later feed into
custom_make_unique). It appears that VisualStudio can only warn if there is a definite sign conversion issue. See the following program:Try it online.