произвольное значение для переменной enum - PullRequest
0 голосов
/ 10 января 2012

Есть этот код.

#include <iostream>
#include <climits>
enum e  {zero,one};
void main()
{
    e num=(e)INT_MAX;
    std::cout<<num;
}

Это определяется стандартом, что вывод будет 2147483647 (при условии sizeof (int) = 4 байта)

Ответы [ 6 ]

3 голосов
/ 10 января 2012

Нет;при преобразовании целого числа в перечисление значение перечисления указывается только в том случае, если целое значение находится в пределах диапазона.Из стандарта:

7.2 / 10 Выражение типа арифметики или типа перечисления может быть явно преобразовано в тип перечисления.Значение не изменяется, если оно находится в диапазоне значений перечисления типа перечисления;в противном случае результирующее значение перечисления не определено.

, где «диапазон» описан довольно сложным образом в 7.2 / 7 и, по существу, увеличивается до наименьшего значения 2^M-1, которое не меньшенаибольшее определенное значение.

Компилятору разрешено использовать любой целочисленный тип для представления перечисления, если он достаточно большой, чтобы содержать все значения перечисления;поэтому в этом случае можно использовать меньший тип, чем int, например char.Кроме того, INT_MAX гарантированно будет не менее 32767.

2 голосов
/ 10 января 2012

Во-первых, нет гарантии, что INT_MAX - это 2147483647. Во-вторых, нет гарантии, что у вашего перечисления будет базовый тип, способный хранить 2147483647 или хранить любое значение INT_MAX.

Теперь, если вы хотите знать, можете ли вы использовать значения, для которых не определен перечислитель, тогда ответ «да». Вы можете использовать значения без соответствующего перечислителя, если значение соответствует диапазону перечисления. Максимальное значение в этом диапазоне - наименьшее 2 ^ n - 1, которое больше или равно всем перечислителям. В вашем случае диапазон составляет [0,1], поэтому никакие другие значения не могут быть использованы четко определенным образом.

В следующем коде диапазон перечисления равен [0,3], поэтому 3 является допустимым значением, даже если для него нет перечислителя.

#include <iostream>

enum e  {zero,one,two};
void main()
{
    e num=(e)3;
    std::cout<<num; // will print "3"
}

Наименьшее значение в диапазоне равно 0, если нет перечислителей с отрицательными значениями. Если есть перечислители с отрицательными значениями, это зависит от представления, используемого реализацией. Если реализация использует дополнение до двух, это - (max + 1), в противном случае это просто -max. В основном, если есть отрицательные значения, диапазон имеет еще один бит:)

#include <iostream>

enum e  {minus_one=-1,zero,one,two};
void main()
{
    e num=(e)-3;
    std::cout<<num; // will print "-3"
}

А в C ++ 11 вы можете явно указать базовый тип, если хотите убедиться, что значение будет представимым:

#include <iostream>
#include <cstdint>

enum e : std::int32_t {zero,one};
void main()
{
    e num=(e)2147483647;
    std::cout<<num; // will print "2147483647"
}
0 голосов
/ 10 января 2012

Тип enum arg является целым числом.

enum e{zero, one} 

означает

int zero = 0; int one =1;

, если вы назначите INT_MAX для целочисленного типа arg.

результат равен 2^31

0 голосов
/ 10 января 2012

Нет. 2147483647 вне допустимого диапазона для этого перечисления.

Диапазон перечисления, если нет отрицательных перечислений, составляет от 0 до 2 ^ k - 1, где 2 ^ k - наименьшая степень 2, для которой все перечисления находятся в диапазоне. В этом случае это будет 2 ^ 1. Поэтому любое значение больше 2 для e делает вывод неопределенным.

0 голосов
/ 10 января 2012

Диапазон допустимых значений перечисления для типа перечисления определяется следующим образом в рабочем проекте C ++, раздел 7.2, параграф 7:

Для перечисления, базовый тип которого является фиксированным, значения перечисления являются значениями базового типа. В противном случае для перечисления, где emin является наименьшим перечислителем, а emax является наибольшим, значения перечисления представляют собой значения в диапазоне от bmin до bmax, определяемые следующим образом: пусть K будет 1 для представления дополнения до двух и 0 для единицы дополнение или представление величины знака. bmax - это наименьшее значение, большее или равное max (| emin |? K, | emax |) и равное 2 ^ M? 1, где М - неотрицательное целое число. bmin равно нулю, если emin неотрицателен, а? (bmax + K) в противном случае. Размер наименьшего битового поля, достаточного для хранения всех значений типа перечисления, равен max (M, 1), если bmin равно нулю, и M + 1 в противном случае. Можно определить перечисление, значения которого не определены ни одним из перечислителей. Если список перечислителя пуст, значения перечисления такие, как если бы перечисление имело единственный перечислитель со значением 0.

При преобразовании арифметического типа или типа перечисления в тип перечисления значение не изменяется, если оно находится в диапазоне значений перечисления типа перечисления. В противном случае значение не указано.

Чтобы избежать непредвиденного поведения, конвертируемое значение должно находиться внутри диапазона значений перечисления. Кроме того, если необходимо динамически проверять значения вне диапазона, это необходимо сделать до преобразования.

0 голосов
/ 10 января 2012

Не могу найти прямого объяснения в спецификациях C ++, но его легко вывести. Основной тип enum определяется во время компиляции. Если компилятор видит, что enum e значения легко помещаются в один байт, он может принять решение сделать его типом char.

Это означает, что вы не сможете сохранить INT_MAX в этом enum.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...