Каковы макроопределения в перечислении событий epoll? [Дубликат]

Один общий подход, о котором я не упоминал здесь, заключается в том, чтобы запустить HTML через Tidy , который может быть настроен на выдачу гарантированного действительного XHTML. Затем вы можете использовать любую старую библиотеку XML.

Но к вашей конкретной проблеме вы должны взглянуть на этот проект: http://fivefilters.org/content-only/ - это модифицированная версия алгоритма Readability , который предназначен для извлечения только текстового содержимого (а не верхних и нижних колонтитулов) со страницы.

3
задан Haswell 4 January 2016 в 07:40
поделиться

2 ответа

Значение RTNLGRP_NEIGH будет равно 3. Вы можете легко проверить это с помощью следующей программы.

#include <stdio.h>

/* RTnetlink multicast groups */
enum rtnetlink_groups {
        RTNLGRP_NONE,
#define RTNLGRP_NONE            RTNLGRP_NONE
        RTNLGRP_LINK,
#define RTNLGRP_LINK            RTNLGRP_LINK
        RTNLGRP_NOTIFY,
#define RTNLGRP_NOTIFY          RTNLGRP_NOTIFY
        RTNLGRP_NEIGH,
#define RTNLGRP_NEIGH           RTNLGRP_NEIGH
        RTNLGRP_TC,
#define RTNLGRP_TC              RTNLGRP_TC
        RTNLGRP_IPV4_IFADDR,
#define RTNLGRP_IPV4_IFADDR     RTNLGRP_IPV4_IFADDR
        /* ... */
#define RTNLGRP_PHONET_IFADDR   RTNLGRP_PHONET_IFADDR
        RTNLGRP_PHONET_ROUTE,
#define RTNLGRP_PHONET_ROUTE    RTNLGRP_PHONET_ROUTE
        __RTNLGRP_MAX
};
#define RTNLGRP_MAX     (__RTNLGRP_MAX - 1)

int
main()
{
  printf("RTNLGRP_NEIGH = %d\n", RTNLGRP_NEIGH);
}

Он выводит это:

RTNLGRP_NEIGH = 3

Поскольку каждый макрос #define d для своего имени, RTNLGRP_NEIGH в main будет заменен на RTNLGRP_NEIGH. Но так как расширение не является рекурсивным, оно останавливается в этой точке, и программа использует константу enum, которая является четвертой и поэтому имеет значение 3.

Если вы не знаете, что препроцессор, вы всегда можете скомпилировать с помощью переключателя -E и посмотреть на предварительно обработанный вывод. Компиляция приведенного выше примера с gcc -E дает (не отображая 840 строк стандартных заголовков библиотеки #include d)

# 4 "main.c"
enum rtnetlink_groups {
        RTNLGRP_NONE,

        RTNLGRP_LINK,

        RTNLGRP_NOTIFY,

        RTNLGRP_NEIGH,

        RTNLGRP_TC,

        RTNLGRP_IPV4_IFADDR,



        RTNLGRP_PHONET_ROUTE,

        __RTNLGRP_MAX
};


int
main()
{
  printf("RTNLGRP_NEIGH = %d\n", RTNLGRP_NEIGH);
}

, который, надеюсь, гораздо менее запутанным.

#define s, смешанные с определением enum, не влияют на определение enum. Не имеет значения, где находятся #define s. Они могли (и, вероятно, должны были) быть размещены до или после определения.

/* RTnetlink multicast groups */
enum rtnetlink_groups {
        RTNLGRP_NONE,
        RTNLGRP_LINK,
        RTNLGRP_NOTIFY,
        RTNLGRP_NEIGH,
        RTNLGRP_TC,
        RTNLGRP_IPV4_IFADDR,
        /* ... */
        RTNLGRP_PHONET_ROUTE,
        __RTNLGRP_MAX
};

#define RTNLGRP_NONE            RTNLGRP_NONE
#define RTNLGRP_LINK            RTNLGRP_LINK
#define RTNLGRP_NOTIFY          RTNLGRP_NOTIFY
#define RTNLGRP_NEIGH           RTNLGRP_NEIGH
#define RTNLGRP_TC              RTNLGRP_TC
#define RTNLGRP_IPV4_IFADDR     RTNLGRP_IPV4_IFADDR
#define RTNLGRP_PHONET_IFADDR   RTNLGRP_PHONET_IFADDR
/* ... */
#define RTNLGRP_PHONET_ROUTE    RTNLGRP_PHONET_ROUTE
#define RTNLGRP_MAX     (__RTNLGRP_MAX - 1)

Причина, по которой они написали этот прошитый код, вероятно, что они хотели реорганизовать старый код с помощью

#define RTNLGRP_NONE          0
#define RTNLGRP_LINK          1
#define RTNLGRP_NOTIFY        2
#define RTNLGRP_NEIGH         3
#define RTNLGRP_TC            4
#define RTNLGRP_IPV4_IFADDR   5
/* ... */

использовать вместо enum. Но поскольку существующий код может полагаться на то, что идентификаторы являются макросами (например, тестирование #ifdef RTNLGRP_NEIGH), они хотели бы предоставить макросы с одинаковым значением. Обратите внимание, что этот подход является ошибочным, поскольку препроцессор не знает значения константы, поэтому вы не можете делать такие вещи, как #if RTNLGRP_NEIGH >= 3, которые вы могли бы, RTNLGRP_NEIGH были #define d до 3 буквально. Таким образом, по сути, их подход сочетает в себе недостатки использования макросов (загрязнение именных пространств) с использованием методов enum s (недоступно во время предварительной обработки).

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

enum rtnetlink_groups {
        RTNLGRP_NONE
#define RTNLGRP_NONE            0
        = RTNLGRP_NONE,
        RTNLGRP_LINK
#define RTNLGRP_LINK            1
        = RTNLGRP_LINK,
        RTNLGRP_NOTIFY
#define RTNLGRP_NOTIFY          2
        = RTNLGRP_NOTIFY,
        RTNLGRP_NEIGH
#define RTNLGRP_NEIGH           3
        = RTNLGRP_NEIGH,
        RTNLGRP_TC
#define RTNLGRP_TC              4
        = RTNLGRP_TC,
        RTNLGRP_IPV4_IFADDR
#define RTNLGRP_IPV4_IFADDR     5
        = RTNLGRP_IPV4_IFADDR,
        /* ... */
};

, которые будут предварительно обработаны следующим.

enum rtnetlink_groups {
        RTNLGRP_NONE

        = 0,
        RTNLGRP_LINK

        = 1,
        RTNLGRP_NOTIFY

        = 2,
        RTNLGRP_NEIGH

        = 3,
        RTNLGRP_TC

        = 4,
        RTNLGRP_IPV4_IFADDR

        = 5,

};

Обратите внимание, что здесь что #define s смешиваются с определением enum, иначе мы получили бы недопустимый код, например 3 = 3,, а не желаемый RTNLGRP_NEIGH = 3.

О, и, пожалуйста, не делайте используйте __RTNLGRP_MAX как идентификатор. Имена, содержащие два смежных подчеркивания или начинающиеся с символа подчеркивания, за которым следует буква верхнего регистра, зарезервированы по стандарту C. Использование их в вашем собственном коде приводит к неопределенному поведению.

5
ответ дан 5gon12eder 28 August 2018 в 12:53
поделиться

Значение RTNLGRP_NEIGH будет равно 3 (это четвертая константа перечисления: RTNLGRP_NONE имеет значение 0, RTNLGRP_LINK имеет значение 1, а RTNLGRP_NOTIFY имеет значение 2).

Материал #define несколько странный - это то, что может заставить людей хотеть остановить вас, используя предварительный процессор C .

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

Итак, результат заключается в том, что вы можете написать:

#ifdef RTNLGRP_NEIGH
   …code using RTNLGRP_NEIGH…
#endif
4
ответ дан Community 28 August 2018 в 12:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: