No warning on implicit conversion

2019-02-25 04:59发布

// 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?

1条回答
Animai°情兽
2楼-- · 2019-02-25 05:24

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.

查看更多
登录 后发表回答