【问题标题】:No warning on implicit conversion隐式转换没有警告
【发布时间】:2014-08-27 19:06:08
【问题描述】:
// 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;
}

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

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

我正在努力确保p 的构造至少会导致警告(但最好是错误)。

有什么想法吗?是否有一个我不知道的标志会触发正确的行为?

【问题讨论】:

  • 你点击了std::pairtemplate&lt;class U, class V&gt; constexpr pair(U&amp;&amp; x, V&amp;&amp; y);构造函数。由于转换实际上发生在该构造函数内部(在系统标头中),因此您不会收到警告。
  • 如果建筑在图书馆内,我可以理解。但正如你所说,这是在一个模板中......它被编译,因此应该检查。
  • @T.C.应该是答案吗?
  • gcc docs :“在 GCC 处理系统标头时,所有警告,除了由‘#warning’(参见诊断)生成的警告之外,都会被抑制。”见your modified example gives you the expected warning
  • @millsj,谢谢你的工作。当然,现在也有很多其他的废话……只是强调了有多少幕后的魔法被黑在一起。 :(

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


【解决方案1】:

如果您的代码使用了std::pair&lt;uint16_t, uint16_t&gt;constexpr pair(const uint16_t&amp; x, const uint16_t&amp; y); 构造函数,您会收到警告和/或错误。您甚至不需要 -Wconversion 来解决这个问题 - 大括号内的缩小转换会导致程序格式错误。

但是,重载决议选择了std::pairtemplate&lt;class U, class V&gt; constexpr pair(U&amp;&amp; x, V&amp;&amp; y); 构造函数,这是一个更好的匹配。结果,转换发生在你编写的代码中,而不是在构造函数中。由于该构造函数是在系统标头中定义的(请参阅GCC's documentation,提示@quantdev),因此警告会被 GCC 抑制。

虽然您可以使用-Wsystem-headers 来启用来自系统标头的警告,但该选项将产生lots of unrelated warnings,因此与-Werror 的交互非常糟糕。

【讨论】:

    猜你喜欢
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    相关资源
    最近更新 更多