Как записать значения из перечислений с препроцессором в файл - PullRequest
0 голосов
/ 21 марта 2012

Я объявляю перечисление следующим образом:

typedef enum message_t {
    mes_no_error    =   0,  // no message sent
    mes_internal    =   1,  // reserved for internals
    mes_start       =   2,  // when main() is executed
    mes_init        =   3,  // when inits in main() are done
    mes_end         =   4,  // when main() returns
    mes_foo,
    mes_bar,
    mes_joe
} message;

Поскольку это для микроконтроллера, который общается со мной на ПК, я хотел бы знать значения, которые используются для mes_foo, mes_bar, mes_joe....

Я подумал, что мог бы использовать такие директивы компилятора:

#warning "mes_block_01 = " mes_joe

и более поздние, то есть регулярное выражение и выгрузка значений в файл при компиляции программы.Тем не менее, gcc просто говорит мне:

message.h:63:2: Warnung: #warning "mes_block_01 = " mes_joe

без значения, а только с именем enum.

Возможно ли каким-либо образом записать автоматически присвоенные значения из перечислений в файл?Можно ли как-то показать значения констант / определений с помощью препроцессора или во время компиляции?

Ответы [ 3 ]

1 голос
/ 21 марта 2012

Согласно K & R ,

A.8.4 Перечисление

...

Идентификаторы всписок перечислителей объявляется как константы типа int и может появляться везде, где требуются константы.Если никакие перечисления с = не появляются, то значения соответствующих констант начинаются с 0 и увеличиваются на 1 при чтении декларации слева направо.Перечислитель с = дает ассоциированному идентификатору указанное значение; последующие идентификаторы продолжают прогрессию от присвоенного значения

То есть mes_foo=5, mes_bar=6 и mes_joe=7.Вам не нужно ничего делать во время компиляции, чтобы знать эти значения.Их значения фиксированы.

0 голосов
/ 22 марта 2012

@ Хонк сделал это. Он признал, что мне нужна семантическая связь между значениями перечисления и понятным для человека именем, которую легко поддерживать и анализировать с помощью приложения с графическим интерфейсом. Я буду, но

#define MESSAGES \
    X(MES_NO_ERROR, 0) \
    X(MES_INTERNAL, 1) \
    X(MES_START, 2)

в messages.h, а затем в модуле сообщений просто выполните

#define X(a, b) b,
enum messages_t { MESSAGES };
#undef X

Спасибо!

0 голосов
/ 21 марта 2012

См. Ответ Павана о том, как ведут себя перечисления.

Поскольку они ведут себя так, вы никогда не должны просто инициализировать некоторых членов enum. Инициализируйте все или ничего. В противном случае вы можете получить случайные ошибки при написании такого кода:

typedef enum 
{ 
  BLUE=2, 
  BLACK, 
  WHITE=3, 
  YELLOW=7
} Color_t;

Color_t color = BLACK;

if(color == WHITE)
{
  printf("White");  // will get executed with color == BLACK
}

Из-за таких ошибок, как эта, написание наполовину инициализированных перечислений как это запрещено MISRA-C: 2004, 9.3.

...