2016-08-01 16 views
7

g ++ nie trafia do kompilacji kodu następujący fragment:g ++, bitfields i ADL

namespace X { 
    enum En {A, B}; 
    bool test(En e); 
} 

bool check() { 
    union { 
    struct { 
     X::En y:16; 
     X::En z:16; 
    } x; 
    int z; 
    } zz; 
    return test(zz.x.y); 
} 

Błąd daje się następujące

In function 'bool check()': 15 : error: 'test' was not declared in this scope return test(zz.x.y);^15 : note: suggested alternative: 3 : note: 'X::test' bool test(En e); ^~~~ Compilation failed

Jeśli zrobię y stałym członkiem, zamiast bitfield, kod kompiluje się pomyślnie. Wywołanie także nazwy-odstępu test działa również. Clang kompiluje program tak, jak jest, bez żadnych skarg.

Odkładanie biznesu na bok (nie podoba mi się w ogóle, ale ma go codebase) i nie koncentruję się na tym, czy mam gwarancję dopasowania enum do 16-bitowego członka, czy jest coś specjalnego w bitfields co uniemożliwia kopanie ADL, tak jak tego oczekuję?

+0

Jeśli jawnie ustawisz typ: 'enum En: short' kompiluje – hauron

+0

@hauron, ciekawą obserwację, dzięki. – SergeyA

+0

'enum En: int' również się nie kompiluje. Minimalny przykład nie wymaga "union" do wywołania błędu. Błąd jest poprzedzony ostrzeżeniem 'warning: ' :: y' jest zbyt mała, aby pomieścić wszystkie wartości 'enum X :: En''. Jeśli spakowane pole bitowe jest wystarczająco duże, aby pomieścić określony typ (domyślnie "unsigned int") bez obcięcia, to się uda. Wygląda to tak, jakby gcc zdecydował się zignorować parametry, które zostały skrócone, jako prawidłowe wskazówki do ADL. – Ext3h

Odpowiedz

1

Podstawowym typu zwykłego teksty stałe, jest zastosowanie zdefiniowanych:

C++ 03 średnia 7,2/5

The underlying type of an enumeration is an integral type that can represent all the enumerator values defined in the enumeration. It is implementation-defined which integral type is used as the underlying type for an enumeration except that the underlying type shall not be larger than int unless the value of an enumerator cannot fit in an int or unsigned int

Zasadniczy czas struct bitowym teksty stałe jest również realizacja zdefiniowane:

C++ 03 standard 9.6/3

A bit-field shall have integral or enumeration type (3.9.1). It is implementation-defined whether a plain (neither explicitly signed nor unsigned) char, short, int or long bit-field is signed or unsigned.

Tak, ponieważ typ obu X::En y:16 i X::En są definiowane przez implementację, niejawna konwersja między nimi jest również definiowana przez implementację, co, jak sądzę, wyjaśnia różnicę w ADL, którą widzisz w kompilatorach.