Подтвердить что ты не робот

Утилита макросов для перечисления

Один заголовок socket.h в моей системе Linux выглядит следующим образом.

/* Bits in the FLAGS argument to `send', `recv', et al.  */
enum
  {
    MSG_OOB             = 0x01, /* Process out-of-band data.  */
#define MSG_OOB         MSG_OOB
    MSG_PEEK            = 0x02, /* Peek at incoming messages.  */
#define MSG_PEEK        MSG_PEEK
    MSG_DONTROUTE       = 0x04, /* Don't use local routing.  */
#define MSG_DONTROUTE   MSG_DONTROUTE
...

Определение enum является своего рода идиомой для создания констант типа-safe-ish в C, что язык действительно рассматривает как константы времени компиляции.

Мой вопрос: в чем заключается назначение макросов MSG_OOB, MSG_PEEK,... которые расширяются до себя?

4b9b3361

Ответ 1

Стандарт POSIX требует, чтобы "символические константы", такие как MSG_DONTROUTE, были "объектноподобными макросами", а не перечисляемыми. Определение их самих позволяет использовать их в контексте перечисления, а также правильно работать с, например, #ifdef.

Из стандарта POSIX:

Заголовок должен определять следующие символические константы.... MSG_DONTROUTE

и

символическая константа... относится к символу препроцессора C (также без аргументов).

И, наконец, из приложения:

Если константе требуется быть макросом, но также разрешено быть другим типом константы, такой как константа перечисления, для реализаций, которые определяют ее как другой тип константы, макрос обычно определяется следующим образом:

#define macro_name macro_name

Это позволяет приложениям использовать #ifdef и т.д., чтобы определить, определен ли макрос, но макрос не используется в директивах #if препроцессора, поскольку препроцессор будет обрабатывать нерасширенное слово macro_name как имеющее нулевое значение.

Ответ 2

Цель этих определений заключается в том, что приложение может делать что-то вроде

#ifdef MSG_OOB
  some code here
#endif

расширение макросов не является рекурсивным, поэтому оценка макроса MSG_OOB приводит к константе enum MSG_OOB с тем же именем.

Кроме того, константы, объявленные как enum, помогают, например, при отладке.