隐式转换没有警告

时间:2014-08-27 19:06:08

标签: c++ casting g++ type-conversion

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

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

后来,g ++确实抱怨在构造b时隐式转换为uint16_t。

我试图确保p的构造至少会产生警告(但最好是错误)。

有什么想法?是否有我不知道要触发正确行为的旗帜?

1 个答案:

答案 0 :(得分:7)

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

但相反,重载决策选择了-Wconversion的{​​{1}}构造函数,这是一个更好的匹配。因此,转换发生在您编写的代码中,而不是在构造函数内部。由于该构造函数是在系统头中定义的(参见GCC's documentation,帽子提示@quantdev),因此GCC会禁止该警告。

虽然您可以使用std::pair从系统标头启用警告,但该选项会生成lots of unrelated warnings,因此会与template<class U, class V> constexpr pair(U&& x, V&& y);进行非常密切的互动。