Visual Studio 2015:std :: make_unique中没有签名/未签名的不匹配警告



我刚刚在我的代码中找到了一个错误,因为这是一个简单的签名/无符号的不匹配,所以我感到很困惑 - 根本不应该发生,因为我正在编译有警告4,警告是错误。所以我试图复制它,这很简单:

#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;
}

现在我在问自己:这是什么原因?它是VS中的错误,还是STD :: make_unique的一般缺点?有什么方法可以解决吗?(Visual Studio 2015社区更新3(

您看到了几种效果的组合。

  1. 您的main()中的呼叫是完全合法的,因为make_unique模板实例化匹配您送达的签名数据类型。
  2. make_unique的实施不会产生警告,因为警告通常在系统标题内禁用。
  3. Visual Studio似乎无法检测到电位(但没有确定( make_unique中的标志转换问题。

更详细地:

1。模板实例化实际上是合法的。

std::make_unique的典型实现看起来像这样(比较cppreference(:

template <typename T, typename... Args>
inline std::unique_ptr<T> make_unique(Args&&... args)
{
  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

在您的情况下,当您致电std::make_unique<MyClass>(-1)时,模板为实例化用于a 签名整数。因此,您不会在您的代码,因为没有未签名/签名的转换发生。

2。系统标头通常禁用警告。

但是,您可以正确地期望从make_unique发出警告执行。毕竟,当您的签名调用new T(...)时参数,签名/未签名的转换仍会发生。作为一个例子,以以下程序:

#include <memory>
class MyClass
{
public:
  MyClass(unsigned) { }
};
template <typename T, typename... Args>
inline std::unique_ptr<T> custom_make_unique(Args&&... args)
{
  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
int main()
{
  auto uniqueP = custom_make_unique<MyClass>(-1);
  (void) uniqueP;
  return 0;
}

当我使用-Wsign-conversion使用GCC对此进行编译时,我会得到警告

test.cpp:在'std :: simolor_ptr&lt; _tp> custom_make_unique(args&amp;&amp; ...([with t = myClass;args = {int}]':
test.cpp:17:48:此处需要
test.cpp:12:63:警告:从" int"中转换为" unsigned int"可能会改变结果的迹象[-wsign-conversion]
返回std :: unique_ptr(new T(std :: forthrom(args(...((;

所以问题是,为什么您没有对std::make_unique()的警告执行?答案本质上是编译器沉默这些警告其系统标头。例如,<memory>的GCC版本标头包含Pragma

#pragma GCC system_header

一旦该布拉格出现在标题文件中,编译器就不再报告该标头内所有内容的警告。从GCC文档:

标题文件将接口声明为操作系统和运行时 图书馆通常不能用严格符合C写成C。因此,GCC 提供在系统标头中找到的特殊处理中的代码。所有警告,除了 由" #warning"生成的那些(请参阅诊断(,而GCC为 处理系统标头。

另请参阅这个帖子更多细节。据推测,Visual Studio的方法类似编译器(正如您在评论中所写的那样,标题暂时减少警告级别(。

3。看起来您正在遇到VisualStudio限制。

在VisualStudio的情况下,还有其他工作。注意如何上面的海湾合作委员会警告说, May 是一个标志转换问题(取决于关于哪些价值用户将稍后 feed到 custom_make_unique(。它出现该VisualStudio只有在存在确定的标志转换问题时才警告。请参阅以下程序:

#include <iostream>
void f(unsigned) { }
template <typename T>
void g(T val) { f(val); } // GCC issues a warning, VS does NOT
int main()
{
  f(-1); // GCC and VS issue a warning
  g(-1); // no conversion warning here (g<int> instantiated)
}

在线尝试。

相关内容

最新更新