Какой смысл использовать #if MACROVALUE #endif внутри кода?

Обнаружил это в коде и не уверен, в чем смысл.

#if !NO_HW
//code
#endif
saveSettingsFile();
}

Я никогда не видел #if #endif внутри такой функции (SLOT), только традиционные #ifndef #define #endif внутри объявлений заголовочных файлов. Я копался в Интернете и обнаружил, что #if (condition) ..code.. #endif промежуточный код выполняется, когда условие истинно, что я могу понять, но мы #define NO_HW 0 ранее в коде, что означает, что всякий раз, когда вызывается эта функция SLOT, она всегда будет выполнять код между #if ... #endif, поскольку !NO_HW будет всегда возвращать ненулевое значение. NO_HW - это определенное имя_макроса со значением, поэтому мы не можем изменить его где-то позже в нашем коде, поэтому я не понимаю необходимости наличия #if !NO_HW ... #endif в нашем коде в первую очередь, помимо для если пользователь хочет иметь возможность позже отключить этот раздел кода, если определенное оборудование должно быть удалено (для нашего приложения я полагаю, что этот #define описывает аппаратное PXIe). (Я перенимаю чужой код, который в настоящее время работает.)

Как вы думаете, в этом ли смысл кода? Включить/отключить раздел кода в зависимости от того, присутствует ли определенный аппаратный компонент, что делается в коде путем изменения того, что установлено #define NO_HW 0?

//DECLARATIONS
#define NO_HW 0

//later, inside a SLOT function
void MainWindow::setOptions(void)
{
#if !NO_HW //this is the line I don't understand

// lot of regular inline if (statment) inlineAction; lines follow
// ...  
#endif

saveSettingsFile();
}  

Нормальный if относится к тому, что вы указываете промежуточный код выполняется, когда условие истинно, #if будет составлено, если условие истинно.

Vuwox 29.06.2019 00:27

Я понимаю, но зачем кому-то использовать условие, чтобы оператор #if был глобальной переменной? Просто чтобы иметь возможность включать и выключать этот раздел кода?

TJ178 29.06.2019 00:28

Точно. лайк #if _DEBUG printf("This is an extra debug message"); #endif

Vuwox 29.06.2019 00:29

Ах, понял, ладно, не знаю, как пометить вопрос как отвеченный сейчас, но спасибо.

TJ178 29.06.2019 00:31

Почему он будет действовать по-другому вне файла заголовка?

Dave Newton 29.06.2019 00:34

@DaveNewton Я не являюсь опытным кодером, поэтому я согласился с тем, как мы определяем файлы заголовков, чтобы позже мы могли #include "name.h" внутри файла .c или .cpp. Это немного отличается от включения только части кода с помощью #if COND ... #endif. Я не был уверен, спрашиваете ли вы, почему я был сбит с толку, или для разъяснения.

TJ178 29.06.2019 00:38

Директивы препроцессора не «определяют заголовочный файл», они используются где угодно (заголовок или нет), чтобы влиять на поведение во время компиляции, как пожелает разработчик.

Dave Newton 29.06.2019 01:45

@DaveNewton Итак, вы просто говорите, что главное заключается в том, что директивы препроцессора предварительно компилируются процессором до выполнения фактической программы, в основном это определение директив препроцессора. Правильный? Я ценю ваш комментарий, напоминающий мне о том, что, хотя файлы заголовков — это всего лишь одно приложение, основная мысль заключается в другом, но вы могли бы сделать это немного более познавательно, как я уже сказал, я учусь.

TJ178 01.07.2019 19:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
184
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Макросы препроцессора можно использовать для включения/отключения части кода, например:

#if _DEBUG 
    printf("This is an extra debug message"); 
#endif

#define ROUNDING 0
float val = 1.2f;
#if ROUNDING 
    int a = (val + 0.5f); // If ROUNDING was 1, the val could have been rounded instead of floor.
#else 
    int a = val; 
#endif

Оказывается, моя интуиция была верна (что подтверждается в комментариях пользователя @Vuwox). Использование глобальной переменной для условия внутри #if CONDITION ...code #endif внутри функции означает включение/отключение этого раздела кода простым изменением значения макроса, что намного проще сделать с помощью макропеременной, которая определена поверх кода. .

Ответ принят как подходящий

Да, ваша догадка верна. Это часто используется в C/C++, например, чтобы различать разные операционные системы и включать/отключать конфигурации, которые никогда не меняются во время выполнения.

Все это делает препроцессор перед компиляцией кода. gcc -E test.cpp для запуска только стадии препроцессора

// test.cpp 
#include <iostream>
#define PRINT_A

int main(){
        #ifdef PRINT_A
                std::cout << "section a" << std::endl;
        #endif

        #ifdef PRINT_B
                std::cout << "section b" << std::endl;
        #endif

        return 0;
}                     

вывод gcc -E test.cpp

int main(){
  std::cout << "section a" << std::endl;
  return 0;
} 

вывод gcc -D PRINT_B -E test.cpp

int main(){
  std::cout << "section a" << std::endl;
  std::cout << "section b" << std::endl;
  return 0;
} 

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