2016-03-15 36 views
5

Potrzebuję użyć wyliczenia o określonym zakresie, aby można było przekazać je jako określone typy do naszego serializera. Podałem wyraźne liczby całkowite dla członków wyliczenia Enum1.Ostrzeżenie o przekroczeniu wartości gcc "zbyt małe, aby pomieścić wszystkie wartości"

Włożyłem dwa scoped stałe teksty pasujące do opisu powyżej w bitfield zatem

enum class Enum1 { 
    value1 = 0x0, 
    value2 = 0x1, 
    value3 = 0x2 
}; 
enum class Enum2 { 
    value1 = 0x0, 
    value2, 
    value3, 
// ... 
    value14 
}; 

struct Example { 
    Enum1 value1 : 2; 
    Enum2 value2 : 6; 
} 

Teraz gdziekolwiek używam rodzaj Example, pojawia się ostrzeżenie „«Przykład :: wartosc1»jest zbyt mały, aby pomieścić wszystkich wartości "Enum1" "i podobnie dla Enum2. Zauważ, że tak nie jest w przypadku wartości, które zdefiniowaliśmy, i nie jesteśmy zainteresowani w ogóle z wartościami spoza nich.

To dość poważna rozproszenie w naszym procesie kompilacji - projekt jest duży i złożony i nie chcemy skanować wielu z tych ostrzeżeń (i jest ich wiele).

Szukałem flagi GCC (G ++), aby wyłączyć określone ostrzeżenie. Czy jest taki, który mogę przekazać w linii poleceń? Idealnie, chciałbym użyć ostrzeżenia pragma, aby wyłączyć go lokalnie, jeśli to możliwe.

Istnieje niewiele możliwości zmiany struktury kodu w tym momencie, ale możemy naprawdę użyć tych fałszywych ostrzeżeń usuniętych.

Z góry dziękuję.

Edycja: Dodano nagłówek o zmienionej nazwie z zmienionymi identyfikatorami.

+1

jeśli Enum1 zawiera wartości większe niż 3, to nie zmieści się na 2 bitach – nikniknik2016

+0

Czy możesz pokazać definicję 'Enum1' i' Enum2'? – Angew

+0

@ nikniknik2016: To nie jest – jsren

Odpowiedz

4

Problem polega na tym, że zakres enum zawsze ma integralny rodzaj. Domyślnie jest to int, ale można go zmienić na dowolny inny typ integralny, taki jak unsigned char.

Niestety, nie można zmienić typu bazowego na pole bitowe, ponieważ nie są one rzeczywistymi typami C++.

można spróbować wyłączyć ostrzeżenie, ale szybki odtłuszczone przez g ++ kod ujawnia te linie (gcc/cp/class.c:3468)

else if (TREE_CODE (type) == ENUMERAL_TYPE 
      && (0 > (compare_tree_int 
        (w, TYPE_PRECISION (ENUM_UNDERLYING_TYPE (type)))))) 
    warning_at (DECL_SOURCE_LOCATION (field), 0, 
       "%qD is too small to hold all values of %q#T", 
       field, type); 

Kluczem tutaj jest wywołanie warning_at(...) zamiast warning(OPT_to_disable_the_warning, ...). Obecnie nie ma opcji, aby ją wyłączyć. Z wyjątkiem ponownej kompilacji samego kompilatora!

Za to, co warto zaznaczyć w CLang ++ - 3.7.1 nie ostrzega o tym.

+0

Pozdrawiam. Tbh Myślę, że to użyteczne ostrzeżenie. Gdyby miał lepszy opis. I naprawdę tylko za pierwszym razem.Moim głównym problemem jest to, że występuje on wiele razy dla każdego pola i dla każdej jednostki kompilacji. Pomimo użycia tylko jednej inwokacji g ++. Jaki jest najlepszy sposób na popychanie deweloperów w tej sprawie? – jsren