Что означает _BIG_ENUM = 0xFFFFFFFF в последнем из перечисления? - PullRequest
2 голосов
/ 17 октября 2019

Я читаю некоторые коды и нашел это _BIG_ENUM = 0xFFFFFFFF в последнем значении enum. Каково правильное значение этой строки. И этот _BIG_ENUM не используется нигде в коде;

#define CLS_COMM_CONFIG PORT_0,BAUD_9600,DATA_BIT_8,ONE_STOP,NO_FLOW_CONTROL
#define PLS_COMM_CONFIG PORT_1,BAUD_115200,DATA_BIT_8,ONE_STOP,NO_FLOW_CONTROL

typedef enum _comm_config
{

 _Zero=0,
 PORT_0=_Zero,
 BAUD_2400=_Zero,
 NONE=_Zero,
 HALF_STOP=_Zero,
 DATA_BIT_5=_Zero,
 NO_FLOW_CONTROL=_Zero,

 _One = 1,
 PORT_1=_One,
 BAUD_4800=_One,
 ODD=_One,
 ONE_STOP=_One,
 DATA_BIT_6=_One,

 _Two=2,
 PORT_2=_Two,
 BAUD_9600=_Two,
 EVEN=_Two,
 TWO_STOP=_Two,
 DATA_BIT_7=_Two,

 _Three=3,
 PORT_3=_Three,
 BAUD_19200=_Three,
 DATA_BIT_8=_Three,

 _Four=5,
 PORT_5=_Four,
 BAUD_115200=_Four,
 DATA_BIT_9=_Four,

 _BIG_ENUM=0xFFFFFFFF,

}COMMConfig;

Ответы [ 2 ]

5 голосов
/ 17 октября 2019

Это не имеет никакого смысла и является ошибкой.

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

Проблема в том, что при перечислении переменные могут иметь размеры, определенные реализацией, перечисление константы , такие как _BIG_ENUM, всегда типа int 1) .

Но 0xFFFFFFFF не уместится в 32-битномint так что это ошибка. Шестнадцатеричная константа 0xFFFFFFFF на самом деле имеет тип unsigned int (при условии, что она 32-битная) и она не подходит, поэтому будет преобразование, определяемое реализацией, из подписанного в неподписанное. Это означает, что в итоге мы получим значение -1 в системах комплемента 2. Хотя gcc и clang со строгими стандартными настройками даже отказываются компилировать код, когда константе перечисления дается целочисленная константа, большая чем INT_MAX.

Когда она сталкивается с константой перечисления со значением -1, компиляторсвободно выбирать любой тип со знаком 2) для переменных перечисления этого типа, не обязательно 32-битного.

Код можно исправить, изменив его на _BIG_ENUM=INT_MAX, (limit.h). Тогда перечислимый тип станет int или unsigned int.


1) C17 6.7.2.2/1

Выражение, котороеопределяет значение константы перечисления должно быть выражением целочисленной константы, которое имеет значение, представленное как int.

2) C16 6.7.2.2/4

Каждый перечисляемый тип должен быть совместим с char, целочисленным типом со знаком или целочисленным типом без знака. Выбор типа определяется реализацией 128), но должен быть способен представлять значения всех членов перечисления.

128) Реализация может задержать выбор целочисленного типа, пока все константы перечисления не будут иметьбыл замечен.

2 голосов
/ 17 октября 2019

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

Если перечислению назначено 32-разрядное значениеэта оптимизация предотвращается, что приводит к тому, что это перечисление кодируется как 32-разрядное целое число.

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