Как выполнить часть кода внутри функции только один раз, используя #ifndef?

//static int initialized;
void print(struct student *arg) {
  #ifndef first_call
  #define first_call 1
  //if (!initialized) {
    //initialized = 1;
    printf("sizeof(*arg1): %lu\n", sizeof(*arg));
  //}
  #endif
  ...
}

Я хочу выполнить строки кода внутри блока if только один раз.

Конечно, я знаю, как это сделать другим способом (прокомментированная часть).

Но я хочу знать, почему мой код не работает так, как я задумал.

Благодарю.

2 ответа

Решение

Директива препроцессора произойдет во время компиляции. Это означает, что до запуска вашей программы потребуется:

//static int initialized;
void print(struct student *arg) {
  #ifndef first_call
  #define first_call 1
  //if (!initialized) {
    //initialized = 1;
    printf("sizeof(*arg1): %lu\n", sizeof(*arg));
  //}
  #endif
  ...
}

И превратить это в:

//static int initialized;
void print(struct student *arg) {
  #define first_call 1
  //if (!initialized) {
    //initialized = 1;
    printf("sizeof(*arg1): %lu\n", sizeof(*arg));
  //}
  ...
}

Это означает, что то, что вы намеревались, не произойдет. Вы просто определили first_call как 1.

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

Это будет работать:

void print(struct student *arg) 
{
    static bool initialized = false;
    if (!initialized) 
    {
        initialized = true;
        printf("sizeof(*arg1): %lu\n", sizeof(*arg));
    }

    ...
}

Вы идете не в ту сторону. #ifdefЭто команды препроцессора, которые анализируются перед компилятором. Это означает, что все находится внутри #ifdef блок просто удаляется перед компиляцией, если условие не выполняется.

Для вашей конкретной проблемы один из распространенных подходов - использовать статическую переменную:

int my_func()
{
    static int initialized = 0;

    if (!initialized)
    {
        /* Initialize */
        ...

        initialized = 1;
    }

    ...
}
Другие вопросы по тегам