Нет предупреждений о неявном преобразовании

// 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. Однако g++ версии 4.9.1 не жалуется ни на какие преобразования при использовании параметров, указанных в комментарии в начале.

Позже g++ жалуется на неявное преобразование в uint16_t при построении b.

Я пытаюсь убедиться, что конструкция p приведет как минимум к предупреждению (но желательно к ошибке).

есть идеи? Есть ли флаг, о котором я не знаю, чтобы вызвать правильное поведение?


person inetknght    schedule 27.08.2014    source источник
comment
Вы попали в конструктор template<class U, class V> constexpr pair(U&& x, V&& y); std::pair. Поскольку преобразование фактически происходит внутри этого конструктора (в системном заголовке), вы не получите предупреждения.   -  person T.C.    schedule 27.08.2014
comment
Если бы конструкция была внутри библиотеки, я бы мог понять. Но, как вы сказали, это в шаблоне... который компилируется и поэтому должен быть проверен.   -  person inetknght    schedule 27.08.2014
comment
@Т.С. это должен быть ответ?   -  person Slava    schedule 27.08.2014
comment
документы gcc : все предупреждения, кроме тех, которые сгенерированы '#warning ' (см. Диагностика), подавляются, пока GCC обрабатывает системный заголовок. См. ваш измененный пример дает вам ожидаемое предупреждение   -  person quantdev    schedule 27.08.2014
comment
Есть ли способ включить предупреждения для системных заголовков?   -  person inetknght    schedule 27.08.2014
comment
@Аркадий, к сожалению нет.   -  person inetknght    schedule 27.08.2014
comment
@millsj, спасибо, сработало. Конечно, теперь есть куча другого дерьма... просто подчеркивается, сколько закулисной магии собрано воедино. :(   -  person inetknght    schedule 27.08.2014


Ответы (1)


Если бы ваш код использовал конструктор constexpr pair(const uint16_t& x, const uint16_t& y); для std::pair<uint16_t, uint16_t>, вы бы получили предупреждение и/или ошибку. Для этого вам даже не понадобится -Wconversion - сужение преобразований внутри фигурных скобок делает программу неправильной.

Но вместо этого разрешение перегрузки выбрало конструктор template<class U, class V> constexpr pair(U&& x, V&& y); std::pair, который лучше подходит. В результате преобразование происходит не внутри кода, который вы написали, а внутри этого конструктора. Поскольку этот конструктор определен в системном заголовке (см. документацию GCC), tip @quantdev), предупреждение подавляется GCC.

Хотя вы можете использовать -Wsystem-headers для включения предупреждений из системных заголовков, эта опция выдаст множество несвязанных предупреждений а так очень плохо взаимодействует с -Werror.

person T.C.    schedule 27.08.2014