// 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_t
到p
的隐式转换。但是,从版本4.9.1开始,g ++在使用开头的注释中提供的参数时不会抱怨任何转换。
后来,g ++确实抱怨在构造b
时隐式转换为uint16_t。
我试图确保p
的构造至少会产生警告(但最好是错误)。
有什么想法?是否有我不知道要触发正确行为的旗帜?
答案 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);
进行非常密切的互动。