隐式转换没有警告 [英] No warning on implicit conversion

查看:210
本文介绍了隐式转换没有警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  // g ++ sizeofint.cpp --std = c ++ 11 -Wconversion -Wall -Wextra -Werror -pedantic-errors 
#include< iostream>
#include< utility>

int main(int argc,char ** argv){
(void)argc;
(void)argv;
int a = 0x12345678;
std :: cout<< sizeof(int)< ...< sizeof(uint16_t)<< std :: endl;
std :: pair< uint16_t,uint16_t> p {a,a}; // !!!!没有警告或转换错误!
std :: cout<< p.first<< :<< p.second<< std :: endl;
uint16_t b = a; // !!!!正确的行为:-Wconversion触发警告,其中-Werror转为错误
std :: cout< b<< std :: endl;
return 0;
}

使用上面的代码,您可以清楚地看到<$ c当构建 p 时,$ c> int 到 uint16_t 。但是,从版本4.9.1开始的g ++不会在使用注释中提供的参数时抱怨任何转换。



稍后,g ++会抱怨隐式在构建 b 时转换为uint16_t。



我试图确保 p 的建设将导致至少一个警告(但最好是一个错误)。



任何想法?是否有一个标志我不知道要触发正确的行为?

解决方案

如果你的代码使用了 constexpr pair(const uint16_t& x,const uint16_t& y); 构造函数 std :: pair< uint16_t,uint16_t> 得到警告和/或错误。您甚至不需要 -Wconversion - 在括号中缩小转换会导致程序格式错误。



但是,重载分辨率选择 std :: pair ' template 构造函数,这是更好的匹配。结果,转换发生,不是在你写的代码内,而是在构造函数内部。由于该构造函数是在系统标头中定义的(请参阅 GCC的文档)尽管您可以使用 -Wsystem-headers 启用警告,但是GCC会停止警告。



<系统标题的警告,该选项将产生许多不相关的警告,因此与非常严重的互动 -Werror


// g++ sizeofint.cpp --std=c++11 -Wconversion -Wall -Wextra -Werror -pedantic-errors
#include <iostream>
#include <utility>

int main(int argc, char **argv) {
    (void)argc;
    (void)argv;
    int a = 0x12345678;
    std::cout << sizeof(int) << "..." << sizeof(uint16_t) << std::endl;
    std::pair<uint16_t, uint16_t> p{a,a}; // !!!! no warning or error on conversion !!!!
    std::cout << p.first << ":" << p.second << std::endl;
    uint16_t b = a; // !!!! correct behavior: -Wconversion triggers warning, which -Werror turns to an error
    std::cout << b << std::endl;
    return 0;
}

With the above code, you can see clearly a implicit conversion from int to uint16_t when constructing p. However, g++ as of version 4.9.1 does not complain about any conversions when using the parameters provided in the comment at the beginning.

Later, g++ does complain about the implicit conversion to uint16_t when constructing b.

I'm trying to make sure that p's construction will result in at least a warning (but preferably an error).

Any thoughts? Is there a flag I don't know about to trigger the correct behavior?

解决方案

If your code had used the constexpr pair(const uint16_t& x, const uint16_t& y); constructor of std::pair<uint16_t, uint16_t>, you'd get a warning and/or error. You wouldn't even need -Wconversion for this - narrowing conversions inside braces render a program ill-formed.

But instead, overload resolution selected std::pair's template<class U, class V> constexpr pair(U&& x, V&& y); constructor, which is a better match. As a result, the conversion happens, not inside the code you wrote, but inside that constructor. Since that constructor is defined in a system header (see GCC's documentation, hat tip @quantdev), the warning is suppressed by GCC.

While you could use -Wsystem-headers to enable warnings from system headers, that option will produce lots of unrelated warnings and so interacts very badly with -Werror.

这篇关于隐式转换没有警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆