2014-08-27 2 views
3
// 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 привела, по крайней мере, к предупреждению (но предпочтительно к ошибке).

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

+1

Вы выбрали 'std :: pair'' template constexpr pair (U && x, V && y); 'конструктор.Поскольку преобразование действительно происходит внутри этого конструктора (в системном заголовке), вы надеваете –

+1

Если бы конструкция была внутри библиотеки, я мог бы понять. Но, как вы сказали, это шаблон ..., который скомпилирован и поэтому должен быть проверен. – inetknght

+0

@TC, если это будет ответ? – Slava

ответ

7

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

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

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

Смежные вопросы