Можно ли создать нулевую функцию, которая не будет выдавать предупреждения? - PullRequest
1 голос
/ 17 марта 2010

У меня есть регистратор в приложении c ++, которое использует следующее:

#define FINEST(...) Logger::Log(FINEST, _FILE, __LINE, __func, __VA_ARGS_)

Однако я хотел бы отключить эти журналы, поскольку они серьезно влияют на производительность моей системы. И недостаточно просто, чтобы мой регистратор не записывал в системный журнал. Мне действительно нужно избавиться от кода, созданного журналами.

Для этого я изменил определение на:

#define FINEST(...)

Что работает, но это вызывает целую кучу предупреждений в моем коде, поскольку переменные сейчас не используются. Так что я хотел бы иметь своего рода NULL FUNCTION, которая на самом деле не существует, но не будет выдавать предупреждения для неиспользуемых переменных.

Итак, иначе говоря, я хотел бы, чтобы он компилировался без предупреждений (т. Е. Компилятор считает, что переменные используются для функции), но функция фактически не существует в приложении (т. Е. Не приводит к снижению производительности).

Возможно ли это?

Спасибо!

Ответы [ 5 ]

4 голосов
/ 17 марта 2010

Рассматривали ли вы отключение этого конкретного предупреждения вашего компилятора?
Возможно, это не очень хорошая идея, но если вам нужно быстрое и грязное решение ...

3 голосов
/ 18 марта 2010

На comeau и GCC предупреждение исчезает, если вы оберните переменные в sizeof:

#define FINEST(...) ((void)sizeof(__VA_ARGS__))

Чтобы избежать предупреждений в GCC о том, что левая или правая сторона оператора запятой не действует (например, если он расширяется до sizeof(a, b)), вы можете ввести тип debug-nullify, который имеет собственный оператор запятой:

struct debug_nullify { };

// doesn't need a definition
template<typename T>
debug_nullify operator,(debug_nullify, T const &);

#define FINEST(...) ((void)sizeof(debug_nullify(), __VA_ARGS__))

Преимущество sizeof в том, что выражения аргументов не оцениваются.

3 голосов
/ 17 марта 2010

Вы можете определить пустую функцию с неназванными параметрами:

void nullFunc(int, int, int, const char*, ...) {
}

Затем переопределите ваш макрос для вызова этой функции:

#define FINEST(...) nullFunc(FINEST, _FILE, __LINE, __func, __VA_ARGS_)
3 голосов
/ 17 марта 2010
template<bool implemented>
void Logger::Log( ... );

template<>
void Logger::Log<true>( ... )
{
  // with implementation
}

template<>
void Logger::Log<false>( ... )
{
  // without implementation
}

// USE:
#define FINEST(...) Logger::Log<true>(FINEST, _FILE, __LINE, __func, __VA_ARGS_)
// or
#define FINEST(...) Logger::Log<false>(FINEST, _FILE, __LINE, __func, __VA_ARGS_)

// EVEN BETTER (w/o macro):
// flag to switch on/off logging
const bool with_log = true; // or =false

// use   
Logger::Log<with_log>( /* place arguments here */ );
2 голосов
/ 18 марта 2010

Я бы рекомендовал удалить декларации в релизе:

int somefunc(int foo, int bar, void* baz)
    {
    DEBUGVAR(Logger,log);
    int othervar;
    /* stuff */
    MAYBELOG(log,"something happened: %i",othervar);
    /* other stuff */
    return 0;
    }

в определении:

#if DEBUGLEVEL>0
#define DEBUGVAR(type,...) type __VA_ARGS__
#define MAYBELOG(logger,str,...) logstuff(logger,__FLIE__,__LINE__,str,__VA_ARG__)
#else
#define DEBUGVAR(type,...)
#define MAYBELOG(logger,str,...)
#endif
...