Почему перечисление не проверяется компилятором C? - PullRequest
7 голосов
/ 15 сентября 2011

Следующий текст является выдержкой из языка программирования C, 2-е издание , написанного создателем языка C (поэтому я предполагаю, что он правильный):

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

У меня есть некоторые сомнения:

  1. В каких случаях в языке C компилятор не проверяет значение enum?
  2. enum константы по какой-то причине не проверяются. Почему бы и нет? Каковы причины?
  3. Поскольку enum не проверяется компилятором, используется ли enum подвержен ошибкам? Пожалуйста, объясните.

Ответы [ 3 ]

8 голосов
/ 15 сентября 2011
  1. Перечисление похоже на причудливое целое число, и это лучше, чем определение целой загрузки констант или макросов препроцессора в качестве имен для константных значений, которые вы хотите сохранить, потому что компилятор (или редактор) может убедитесь, что вы используете правильные имена и значения для выбора правильного типа. С другой стороны, будучи просто int, ничто не мешает вам ввести значение, для которого вы не сделали имени, что иногда полезно.

  2. Их нельзя проверить в каждом случае. Что если вы добавите два числа вместе, чтобы получить значение, которое будет помещено в переменную типа enum? Это может быть любое значение, сгенерированное во время выполнения, поэтому его нельзя проверить (по крайней мере, без больших накладных расходов).

  3. Все в C небезопасно; практически нет функции, которую компилятор может полностью предотвратить. Перечисления безопасны, потому что они эффективны для предотвращения ошибок и путаницы программистов, а не потому, что они мешают вам делать глупости.

6 голосов
/ 15 сентября 2011

Вы можете сделать перечисление как

enum status {
    ST_READY = 1 << 0, /*  1 */
    ST_WAIT  = 1 << 1, /*  2 */
    ST_ERROR = 1 << 2, /*  4 */
    ST_HALT  = 1 << 3, /*  8 */
    ST_ETC   = 1 << 4, /* 16 */
};

Затем определить объект этого типа

enum status status;

и установить для него побитовое ИЛИ некоторых "простых" состояний

status = ST_WAIT | ST_ERROR; /* recoverable error */

Обратите внимание, что значение ST_WAIT | ST_ERROR равно 6 и что это значение не является частью перечисления.


Чтобы ответить на ваши вопросы:

  1. Компилятор C позволяет программисту выстрелить себе в ногу.
  2. Компилятор C позволяет программисту выстрелить себе в ногу.
  3. Компилятор C позволяет программисту выстрелить себе в ногу.
1 голос
/ 15 сентября 2011

1) При всех случаях в языке C компилятор не проверяет значение, как это касается enum.

Я не могу понять, если говорить о вашем племени.

1) При каких случаях в языке C компилятор не проверяет значение перечисления.[отредактировано]

При назначении на него.Разрешено присваивать пустые целые числа, поэтому вы можете сделать:

enum E { A, B } x;
x = 10000;

без ошибки компилятора.Кроме того, switch es в перечислениях не проверяются на предмет исчерпываемости.

2) Почему константы перечисления не проверяются по некоторым причинам?Каковы эти причины?

Люди любят ставить в них целые числа.например.

enum E { END_OF_EVERYTHING = 5 };

, где 0-4 означают обычные значения, а 5 - особые.

3) Поскольку enum не проверяется компилятором, используя enumподвержен ошибкам?

Да.Поскольку перечисления имеют только значения наименьшего числа битов, которые могут принимать все значения перечисления, вы можете получить странные результаты:

enum E { A = 1, B = -1 };

Это перечисление содержит только 2 бита данных (значения -2, -1, 01).Если вы назначите ему 10000, могут произойти странные вещи (на самом деле это видно).

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