Есть у меня вот такой рабочий файл
#ifndef ANDROID_LOGGING_H
#define ANDROID_LOGGING_H
#include <stdio.h>
#include <android/log.h>
#include <vector>
#define APP_NAME "MyApp"
#define IS_DEBUGG true
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, APP_NAME, __VA_ARGS__))
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, APP_NAME, __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, APP_NAME, __VA_ARGS__))
#define LOGE(...) ((void) __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__))
#define CHECK(condition) \
if (!(condition)) { \
LOGE("*** CHECK FAILED at %s:%d: %s", __FILE__, __LINE__, #condition); \
abort(); \
}
#endif //ANDROID_LOGGING_H
Я вижу, что в макросе CHECK
используется условие
#define CHECK(condition) \
if (!(condition)) { \
LOGE("*** CHECK FAILED at %s:%d: %s", __FILE__, __LINE__, #condition); \
abort(); \
}
Значит использовать условия в макросах можно, от сюда я придумал дописать условие в лог
Вот так
#define LOGE(...) ((void) if(IS_DEBUGG) __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__))
Но теперь везде где я использую LOGE("error");
мне подсвечивает и говорит, что не хватает какого то знака syntax error (, ), ;
Как написать условие в макросе?
EDIT
#define IS_DEBUGG true
#if(IS_DEBUGG)
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, APP_NAME, __VA_ARGS__))
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, APP_NAME, __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, APP_NAME, __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__))
#endif
Это условие не в макросе, а вставляется в код. Условные директивы для препроцессора пишутся так:
#if(IS_DEBUGG)
#define LOGE(...) ((void) __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__))
#else
#define LOGE(...)
#endif
В макросах почти нет никаких "можно" или "нельзя". Макросы - это текстовые подстановки. Писать в них можно почти что угодно. Фактически "использоваться", правда, это все будет не в макросе, а в месте его подстановки.
Вы все сделали почти правильно, кроме какого-то странного (void)
, который вы впихнули в ваш макрос ни к селу, ни к городу. Неудивительно, что в месте подстановки такого макроса возникает ошибка из-за этого (void)
. Правильно
#define LOGE(...)\
if (IS_DEBUGG)\
__android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__)
Можно добавить (void)
непосредственно перед вызовом функции, как это сделано в остальных вызовах, если этого (void)
требует принятые у вас правила написания кода
#define LOGE(...)\
if (IS_DEBUGG)\
((void) __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__))
Однако такой вариант макроса страдает от одной неприятной проблемы, которая присуща и приведенному вами макросу CHECK
тоже. Если кто-то когда-напишет вполне естественно выглядящий код вида
if (условие1)
CHECK(условие2);
else
что-то;
то такой код приведет к ошибке "оторванного" else
.
А если кто-то использует
if (условие)
LOGE(параметры);
else
что-то;
то такой код будет проинтерпретирован компилятором как
if (условие)
if (IS_DEBUGG)
__android_log_print(ANDROID_LOG_ERROR, APP_NAME, параметры);
else
что-то;
То есть else
будет неожиданно отнесен совсем не к тому if
, к которому собирался отнести его автор кода.
По этим причинам при написании подобных макросов следует придерживаться определенных правил. Как минимум, в if
верхнего уровня старайтесь всегда указывать обе ветки if
и ваш код писать именно в ветке else
#define CHECK(condition) \
if (condition); else { \
LOGE("*** CHECK FAILED at %s:%d: %s", __FILE__, __LINE__, #condition); \
abort(); \
}
#define LOGE(...) \
if (!IS_DEBUGG); else \
((void) __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__))
Но лучше такие составные макросы всегда заключать в операторные скобки do ... while (0)
#define CHECK(condition) \
do \
if (!(condition)) { \
LOGE("*** CHECK FAILED at %s:%d: %s", __FILE__, __LINE__, #condition); \
abort(); \
} \
while (0)
#define LOGE(...) \
do \
if (IS_DEBUGG) \
(void) __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__); \
while (0)
В вашем случае, когда условие является константой препроцессора (IS_DEBUGG
) лучше, наверное, применить принципиально иной подход из ответа @VTT. Однако это ни в коем случае не обязательно. Ваш оригинальный подход вполне жизнеспособен и обладает своим набором преимуществ.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Суть моей задачи в том , что надо искать определенные лексемы в файлахЕсли лексема есть, то выводить значение после него