г ++ не удается скомпилировать следующий фрагмент кода:г ++, битовые и 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 пинать, как я ожидаю?
Если вы явно задаете тип: 'enum En: short' компилирует – hauron
@hauron, интересное наблюдение, спасибо. – SergeyA
'enum En: int' также не компилируется. Минимальный пример не требует, чтобы 'union' вызывал ошибку. Ошибка предшествует предупреждению 'warning: ' :: y' слишком мало для хранения всех значений« enum X :: En'' ». Если упакованное битовое поле достаточно велико, чтобы удерживать указанный тип (который по умолчанию равен 'unsigned int') без усечения, он преуспевает. Похоже, что gcc выбирает игнорировать параметры, которые были подвергнуты усечению как допустимые подсказки для ADL. –
Ext3h