Являются ли две приведенные ниже конструкции эквивалентными в предположении, что "cond" не конфликтует ни с одним именем в программе
#define DOWHILE do { (some_code); } while (0)
#define FORLOOP for(bool cond = true; cond; cond = false) (some_code)
Цель этого вопроса:
У меня есть что-то вродеthis
bool printLogs; // nonconstant dynamic variable
И у меня есть макрос (я не могу делать большие изменения, это большой проект; мне приходится иметь дело с этим макросом) #define LOG ...
, который используется как
LOG << "message" << 1 << 0.5 << 'a';
И я хочу, чтобы этот макрос превратился в
if (printLogs) {
PrinterClass() << "message" << 1 << 0.5 << 'a';
}
Таким образом, напечатанные аргументы не вычисляются, если не печатаются. В этом случае мое решение будет
#define LOG for(cond = printLogs; cond; cond = false) PrinterClass()
Это решение правильно? Существуют ли другие способы?
ОБНОВЛЕНИЕ: Вы не можете использовать простой if
здесь. Например, этот код не будет работать
#define LOG if(printLogs) PrinterClass()
int main() {
if (1)
LOG << 1;
else
LOG << 2;
}
ОБНОВЛЕНИЕ 2: Я ожидаю увидеть объяснение правильности моего или вашего решения. Я должен быть уверен, что решение не вызовет никаких проблем. Вы можете вставить конструкцию «do while» в любом месте вашего кода, где вы можете вставить оператор. Так что «делай пока» ведет себя как простое утверждение. Это правда для моей конструкции?
ОБНОВЛЕНИЕ 3: Решение с глобальным объектом не удовлетворяет, поскольку это вызовет огромные накладные расходы
#include <atomic>
void printImpl(...);
std::atomic<bool> printLog;
struct Log {
template <typename T>
Log& operator<<(const T& t) {
if (printLog) {
printImpl(t);
}
return *this;
}
};
int main() {
Log() << 1 << 2;
}
После всех оптимизаций будетпревращается в
int main() {
if (printLog) {
printImpl(1);
}
// Still should check because printImpl could have changed this variable.
// C++ does not provide any way to say "I promise it won't change printLog"
if (printLog) {
printImpl(2);
}
}
Таким образом, у вас есть атомное сравнение для каждого использования <<. См <a href="https://godbolt.org/z/sEoUCw" rel="nofollow noreferrer">https://godbolt.org/z/sEoUCw