Im чтение C++, я нашел такое определениеНужна помощь по поводу макроопределении
#define USE_VAL(X) if (&X-1) {}
имеет никого идею, что это значит?
Im чтение C++, я нашел такое определениеНужна помощь по поводу макроопределении
#define USE_VAL(X) if (&X-1) {}
имеет никого идею, что это значит?
Основываясь на названии, это выглядит как способ избавиться от предупреждения «неиспользуемая переменная». Предполагаемое использование, вероятно, что-то вроде этого:
int function(int i)
{
USE_VAL(i)
return 42;
}
Без этого, вы можете получить предупреждение компилятора, что параметр i
не используется внутри функции.
Однако это довольно опасный способ обойти это, потому что он вводит Undefined Behavior в код (арифметика указателя за пределами фактического массива не определена стандартом). Можно добавить 1 к адресу объекта, но не вычесть 1. Конечно, с + 1
вместо - 1
компилятор мог тогда предупредить о том, что «условие всегда истинно». Это возможно, что оптимизатор удалит весь if
, и код останется в силе, но оптимизаторы становятся лучше использовать «неопределенное поведение не может произойти», что действительно может испортить код совершенно неожиданно.
Не говоря уже о том, что operator&
может быть перегружен для соответствующего типа, что может привести к нежелательным побочным эффектам.
Есть более эффективные способы реализации такой функциональности, такие как литье в void
:
#define USE_VAL(X) static_cast<void>(X)
Однако мое личное предпочтение закомментировать имя параметра в определении функции, например:
int function(int /*i*/)
{
return 42;
}
Преимущество этого в том, что оно фактически предотвращает случайное использование параметра после передачи его макросу.
Да, для этого последнего подхода. Это, безусловно, самый простой и не включает ** добавление ** кода, который намеренно ничего не делает, чтобы успокоить предупреждение компилятора. –
Обычно необходимо избегать предупреждения о неиспользованном возврате. Даже если обычная идиома «литой на пустоту» обычно работает для неиспользуемых функциональных параметров, gcc
с -pedantic
особенно строг при игнорировании возвращаемых значений таких функций, как fread
(в общем, функции, отмеченные __attribute__((warn_unused_result))
), поэтому «подделка if
» часто используется для обмана компилятора, думая, что вы что-то делаете с возвращаемым значением.
Вы не можете взять адрес rvalue, так что это не может работать для большинства возвращаемых значений. – Angew
Макрос - это предпроцессорная директива, означающая, что везде, где он используется, он будет заменен соответствующим фрагментом кода.
и здесь после USE_VAL (X) пространство объясняет, что сделает USE_VAL (X).
сначала он берет адрес x, а затем вычитает из него 1. если это 0, ничего не делайте.
где USE_VAL (X) будет использоваться он будет заменен, если (& X-1) {}
Макросы не являются функциями. – LogicStuff
есть макрос не функция. но для недоразумения вы можете подумать, используя эту концепцию. –
@ KashifArif Нет, NO, ** NO **. Не думайте о макросах как о функциях. Они * даже не удаленно закрыты. * Макрос является чисто синтаксической заменой. Размышление о макросах, таких как функции, приводит ко всем видам ошибок и недоразумений. – Angew
Вы используете это, чтобы избавиться от неиспользованного предупреждения параметра? – LogicStuff
Что касается 'if' - автор, возможно, пытался это сделать: http://stackoverflow.com/questions/154136/do-while-and-if-else-statements-in-c-c-macroshttp://stackoverflow.com/questions/154136/do-while-and-if-else-statements-in-cc-macro – LogicStuff
Я хочу знать, для чего это используется, потому что у меня есть код, который хотел бы работать с этим кодом. –