Можно ли использовать функцию #define внутри функции?

например, я видел исходный код, как поток. Можем ли мы использовать #define в функции? как это работает? (дополнительная информация: этот код - это то, что я копирую из openvswitch исходного кода):

void *
ofputil_put_action(enum ofputil_action_code code, struct ofpbuf *buf)
{
switch (code) {
case OFPUTIL_ACTION_INVALID:

#define OFPAT13_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM:
#include "ofp-util.def"
    OVS_NOT_REACHED();

#define OFPAT10_ACTION(ENUM, STRUCT, NAME)                  \
case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)      \
case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)        \
case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
#include "ofp-util.def"
}
OVS_NOT_REACHED();
}

#define OFPAT10_ACTION(ENUM, STRUCT, NAME)                        \
void                                                        \
ofputil_init_##ENUM(struct STRUCT *s)                       \
{                                                           \
    memset(s, 0, sizeof *s);                                \
    s->type = htons(ENUM);                                  \
    s->len = htons(sizeof *s);                              \
}                                                           \
                                                            \
struct STRUCT *                                             \
ofputil_put_##ENUM(struct ofpbuf *buf)                      \
{                                                           \
    struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s);   \
    ofputil_init_##ENUM(s);                                 \
    return s;                                               \
}
#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
OFPAT10_ACTION(ENUM, STRUCT, NAME)
#define OFPAT13_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
OFPAT10_ACTION(ENUM, STRUCT, NAME)
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)            \
void                                                        \
ofputil_init_##ENUM(struct STRUCT *s)                       \
{                                                           \
    memset(s, 0, sizeof *s);                                \
    s->type = htons(OFPAT10_VENDOR);                        \
    s->len = htons(sizeof *s);                              \
    s->vendor = htonl(NX_VENDOR_ID);                        \
    s->subtype = htons(ENUM);                               \
}                                                           \
                                                            \
struct STRUCT *                                             \
ofputil_put_##ENUM(struct ofpbuf *buf)                      \
{                                                           \
    struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s);   \
    ofputil_init_##ENUM(s);                                 \
    return s;                                               \
}
#include "ofp-util.def"

Ответ 1

#define - это директива препроцессора: она используется для генерации возможного кода С++ , прежде чем обрабатывается компилятором, который сгенерирует исполняемый файл. Поэтому код вроде:

for(int i = 0; i < 54; i++) {
  #define BUFFER_SIZE 1024
}

не, выполняемый 54 раза (на уровне препроцессора): препроцессор просто работает над циклом for (не зная, что такое цикл for), видит оператор определения, связывает 1024 с BUFFER_SIZE и продолжается. Пока он не достигнет дна файла.

Вы можете написать #define всюду, поскольку препроцессор не знает о самой программе.

Ответ 2

Конечно, это возможно. #define обрабатывается препроцессором перед компилятором. Это простая замена текста. Препроцессор даже не знает, находится ли строка кода внутри или вне функции, класса или любого другого.

Кстати, обычно считается, что плохой стиль определяет макросы препроцессора в С++. Большинство вещей, для которых они используются, могут быть лучше достигнуты с помощью шаблонов.

Ответ 3

Как это работает? Все файлы C/С++ сначала обрабатываются... препроцессором.

Он ничего не знает о синтаксисе C или С++. Он просто заменяет THIS_THING на ANOTHER THING. Вот почему вы можете также размещать #define в функциях.

Ответ 4

Конечно. #define обрабатывается препроцессором, который возникает задолго до того, как компилятор имеет какое-либо чувство линий кода внутри функций, внутренних списков параметров, внутри структур данных и т.д.

Поскольку препроцессор не имеет понятия о функциях С++, это также означает, что для определения макросов нет естественной области. Поэтому, если вы хотите повторно использовать имя макроса, вам нужно #undef NAME, чтобы избежать предупреждений.

Ответ 5

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

Ответ 6

Вы можете использовать #define в любом месте. Он не знает о функциях и не связан их сферой действия. Когда препроцессор сканирует файл сверху вниз, он обрабатывает #define по мере их просмотра. Не вводите в заблуждение (глупым кодом, подобным этому!), Полагая, что #define каким-то образом обрабатывается только при вызове функции; это не так.