Сохранение совместимости ABI с C ++ 11 `enum class`

Это почти такой же вопрос, как Влияет ли добавление перечислителей в enum?, но с enum class введено C ++ 11.

За что я понимаю эта страница Я могу просто иметь стабильный ABI, определяя базовый тип для моего перечисления:

enum class Foo : uint32_t
{
x, y, z
}

Я бы сказал, что это прекрасно работает, как, например, что-то вроде

enum class Foo : uint8_t { x = 257 }

Не будет компилироваться. Это подразумевает, что компилятор больше не изменяет размер моего перечисления в молчании, поэтому я не нарушаю двоичную совместимость.

Я прав?

2

Решение

я верю принятый ответ на указанный вопрос отвечает на большинство вопросов относительно совместимости ABI. Я мог бы повторить это здесь, но я не вижу большой ценности там.

Чтобы ответить на конкретный вопрос о перечислениях C ++ 11 в вашем примере:

enum class Foo : uint8_t { x = 257 }

неправильно сформирован, поскольку требует сужающего преобразования, реализация должна предоставлять диагностику, но она может компилироваться, если реализация только предупреждает, например. Как вы спросите, компилятор не будет молча менять размер базового типа.

Мы можем видеть это из проекта стандарта C ++ dcl.enump5:

Каждое перечисление определяет тип, который отличается от всех других типов. Каждое перечисление также имеет базовый тип. Базовый тип может быть явно указан с помощью enum-base. Для перечисляемого типа с ограниченным диапазоном базовым типом является int, если он не указан явно. В обоих этих случаях базовый тип считается фиксированным. После закрывающей скобки спецификатора перечисления каждый перечислитель имеет тип своего перечисления. Если базовый тип является фиксированным, тип каждого перечислителя перед закрывающей скобкой является базовым типом, а константное выражение в определении перечислителя должно быть преобразованным константным выражением базового типа.. Если базовый тип не является фиксированным, тип каждого перечислителя перед закрывающей скобкой определяется следующим образом: …

а также преобразованное константное выражение запретить сужение конверсии, из expr.constp5:

Преобразованное константное выражение типа T является выражением, неявно преобразованным в тип T, где преобразованное выражение является константным выражением, а последовательность неявного преобразования содержит только

  • интегральные преобразования кроме сужения конверсий,

1

Другие решения

ОП здесь.

Я узнал, и я думаю, что было бы уместно упомянуть, что C ++ 11 имеет этот хороший станд :: underlying_type.

Я думаю, что это может быть использовано вместе с такой же
а также
статические утверждения, создать некоторую защиту от неожиданных изменений ABI из-за перечислений.

Я думаю (но я не пытался), что это особенно актуально, если кто-то работает с какой-то библиотекой, а уже существующее перечислительное не указывает базовый тип.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector