Я читал о __noop и пример MSDN
#if DEBUG
#define PRINT printf_s
#else
#define PRINT __noop
#endif
int main() {
PRINT("\nhello\n");
}
и я не вижу выгоды по сравнению с пустым макросом:
#define PRINT
Сгенерированный код такой же. Что является действительным примером использования __noop
что на самом деле делает это полезным?
__noop
intrinsic указывает, что функция должна игнорироваться, а список аргументов анализироваться. но код для аргументов не генерируется. Он предназначен для использования в глобальных функциях отладки, которые принимают переменное число аргументов.
В вашем случае аргумент является выражением без побочных эффектов, которое можно легко оптимизировать, поэтому это не имеет значения.
Но если выражение аргумента имеет побочные эффекты или является настолько сложным, что компилятор не может доказать, что оно нормально завершается и не имеет побочных эффектов, тогда с помощью __noop
предотвращает потенциально дорогую оценку этого выражения.
Второе преимущество заключается в том, что он ведет себя как вызов функции с переменным числом аргументов синтаксически. Таким образом, замена его на вызов функции не влияет на разбор программы. С некоторыми другими заменами (такими как пустая строка) это может быть проблемой в некоторых ситуациях.
#define PRINT
extern int some_complicated_calculation();
PRINT("%d\n", some_complicated_calculation());
вызовет функцию, даже если вы не хотите результата.
С помощью __noop
функция не будет вызвана.
Вы можете (при условии, что компилятор поддерживает переменные макросы) определить PRINT
игнорировать аргументы; но тогда они вообще не будут анализироваться и могут стать недействительными, если вы измените код вокруг них без компиляции варианта, который определяет PRINT
сделать что-то. С помощью __noop
аргументы все еще анализируются, поэтому, скорее всего, останутся действительными.