2016-08-01 3 views
7

г ++ не удается скомпилировать следующий фрагмент кода:г ++, битовые и 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); 
} 

Ошибка дает следящие

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

Если я сделать y постоянным членом, а не битовое поле, код успешно компилируется. Вызов с номером test также работает. Clang компилирует программу как есть без каких-либо жалоб.

Отправлять битбитный бизнес в сторону (мне это совсем не нравится, но есть кодовая база), и не фокусируясь на том, есть ли у меня гарантия установить перечисление в 16-битный элемент или нет, есть ли что-то особенное в отношении бит-полей что мешает ADL пинать, как я ожидаю?

+0

Если вы явно задаете тип: 'enum En: short' компилирует – hauron

+0

@hauron, интересное наблюдение, спасибо. – SergeyA

+0

'enum En: int' также не компилируется. Минимальный пример не требует, чтобы 'union' вызывал ошибку. Ошибка предшествует предупреждению 'warning: ' :: y' слишком мало для хранения всех значений« enum X :: En'' ». Если упакованное битовое поле достаточно велико, чтобы удерживать указанный тип (который по умолчанию равен 'unsigned int') без усечения, он преуспевает. Похоже, что gcc выбирает игнорировать параметры, которые были подвергнуты усечению как допустимые подсказки для ADL. – Ext3h

ответ

1

Основной типа простых перечислений определяется реализацией:

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

Основополагающий время STRUCT битовых перечислений также определяются реализация:

C++ 03 стандарт 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.

Так, так как тип и X::En y:16 и X::En являются определяемыми реализацией, неявное преобразование между ними также определяется реализацией, что, я думаю, объясняет разницу ADL, которую вы видите через компиляторы.

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