2013-06-20 5 views
7

Natknąłem się na kłopotliwą sytuację, w której znalazłem oczywistą zwężającą się konwersję, ale jestem rozczarowany, że kompilator (gcc-4.7.2) nie podniósł ostrzeżenia pomimo flag -Wall -Wnarrowing -pedantic. Proszę zapoznać się z następującym programem:Brak ostrzeżenia o zwężeniu podczas inicjowania za pomocą nawiasów

struct A { 
    int m; 
    A(int m) : m(m) {}; 
}; 

int main() { 
    unsigned long v = 0; 
    A a1(v); // narrowing, but no warning (should this not cause a warning?) 
    A a2{v}; // narrowing, warning raised (expected) 
} 

Inicjacja a1 wydaje się latać bez tylu jako peep od kompilatora. Aby upewnić się, że nie szaleję, próbowałem zainicjować a1 w ten sam sposób, ale z nawiasami klamrowymi zamiast parens. Kompilator ostrzega o zwężeniu w drugim przypadku, zgodnie z oczekiwaniami.

Aby było jasne: nie pytam o legalność zawężania konwersji na listach inicjalizacyjnych. Wiem, że to nie jest legalne - inicjowanie kędzierzawe a2 było tylko sprawdzianem zdrowego rozsądku. Moje pytanie nie ma związku z listami inicjalizacyjnymi. To nie jest duplikat pytania.

Czy kompilator nie ostrzega mnie o zwężeniu w celu inicjalizacji a1?

+0

Konstruktor dla 'a1' może wykonać jedną niejawną konwersję, podczas gdy dla' a2' nie może. Jak myślisz, dlaczego oni powinni być tacy sami? –

+1

Co się stanie, jeśli dodasz flagę '-Wconversion'? –

+0

To nie jest duplikat. Mam już świadomość, że zawężanie konwersji na listach inicjujących jest nielegalne. Pytam o wstępną inicjał z nawiasami. –

Odpowiedz

2

Wsign-conversion wygeneruje ostrzeżenie dla tej linii kodu - -Wconversion nie będzie kiedy unsigned long i int mają tę samą wielkość (co jest prawdą na wielu platformach, nawet niektórych platformach 64-bitowych). Dla kodu C, -Wconversion niejawnie włączy -Wsign-conversion, ale z jakiegoś powodu tak się nie dzieje z C++.

Jeśli zmienić typ v do long long, -Wconversion sam wygeneruje ostrzeżenie (zakładając, że int jest 32-bitów).

+0

Dziękuję bardzo za twój wgląd. Cieszę się, że semantyka listy inicjalizacyjnej jest bardzo specyficzna dla konwersji - może to być dobry powód, dla którego zacznę używać '{}' wszędzie tam, gdzie potrzebuję kodu, aby być najbardziej przenośnym, aby kompilator mógł przechwycić pułapki konwersji zanim faktycznie celuję nowa platforma. –

Powiązane problemy