2016-08-01 16 views
7

g ++ folgenden Code-Schnipsel kompilieren fehlschlägt:g ++, bitfields und 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); 
} 

Der Fehler gibt es folgt

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

Wenn ich y ein reguläres Mitglied zu machen, anstatt ein Bitfeld, Code kompiliert erfolgreich. Das Aufrufen eines Namens-Abstandes test funktioniert auch. Clang kompiliert das Programm so, wie es ist, ohne sich zu beschweren.

Bitfield-Geschäft zur Seite legen (ich liebe es überhaupt nicht, aber Codebase hat es) und sich nicht darauf konzentrierend, ob ich eine Garantie habe, eine Enum in das 16-Bit-Mitglied zu passen oder nicht, gibt es etwas Besonderes in Bezug auf Bitfelder was verhindert, dass ADL eintritt, wie ich es erwarte?

+0

Wenn Sie explizit den Typ: 'Enum En: kurz 'setzen es kompiliert – hauron

+0

@ Hauron, interessante Beobachtung, danke. – SergeyA

+0

'enum En: int' kompiliert auch nicht. Minimal Beispiel erfordert nicht die "Union", um den Fehler auszulösen. Dem Fehler geht die Warnung 'warning 'voraus: :: y' ist zu klein, um alle Werte von 'enum X :: En'' zu enthalten. Wenn das gepackte Bitfeld groß genug ist, um den angegebenen Typ (der standardmäßig auf "unsigned int" steht) ohne Abschneiden zu halten, ist es erfolgreich. Es scheint so, als ob gcc beschließt, Parameter, die abgeschnitten wurden, als gültige Hinweise für ADL zu ignorieren. – Ext3h

Antwort

1

der zugrunde liegende Typ Normal enums ist Implementierung definiert:

C++ Standard 03 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

Die zugrunde liegende Zeit der struct Bitfeld enums ist auch die Implementierung definiert:

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.

Also, weil die Art der beiden X::En y:16 und X::En sind implementation-defined, die implizite Konvertierung zwischen ihnen ist ebenfalls implementation-defined, was den ADL-Unterschied erklärt, den Sie über Compiler sehen.