Очистить функцию вывода отладки? - PullRequest
1 голос
/ 19 января 2011

Я хочу написать функцию, которая будет печатать сообщения об ошибках / предупреждения в моей программе вместе с файлом и номером строки.В C есть эти два макроса:

__FILE__
__LINE__

, но, на мой взгляд, есть проблема ... Когда я пишу такую ​​функцию:

#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void error(const char *location, const char *msg)
{
#ifdef DEBUG
  printf("Error at %s: %s\n", location, msg);
#endif
}
int main(int , char**)
{
  error(AT, "fake error");
  return 0;
}

В двоичном файле все еще много бесполезных вызовов функций и мусора (значения __FILE__ и __LINE__ при каждом вызове), даже если я отменяю DEBUG для сборки выпуска.Итак, как я могу сделать это более элегантно?Я хочу что-то вроде этого:

#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void error(const char *location, const char *msg)
{
  printf("Error at %s: %s\n", location, msg);
}
int main(int , char**)
{
#ifdef DEBUG
  error(AT, "fake error");
#endif
  return 0;
}

Но не писать #ifdef DEBUG и #endif до и после каждого вызова функции - это было бы слишком много для такой задачи.И удалять каждый error(AT, "fake error"); звонок вручную тоже не очень элегантно ...

Есть идеи?Может быть, встроить функцию (не поможет, не так ли)?Какой-то макрос или изменение этой конструкции?

Ответы [ 5 ]

3 голосов
/ 19 января 2011

Просто превратите error в макрос:

#ifdef DEBUG
# define ERROR(l, m) error(l, m)
#else
# define ERROR(l, m)
#endif

, затем в своих функциях напишите

ERROR(AT, "fake error");

Конечно, вы также можете упростить ERROR и избавиться от AT в качестве первого параметра, непосредственно указывающего эту информацию в определении макроса.

2 голосов
/ 19 января 2011

Обтекание error() в макросе действительно правильный путь - я бы написал так:

#ifdef DEBUG
static void error(const char *file, long line, const char *msg)
{
  fprintf(stderr, "Error (%s:%ld): %s\n", file, line, msg);
}
#define error(msg) (error)(__FILE__, __LINE__, msg)
#else
#define error(msg) ((void)0)
#endif
2 голосов
/ 19 января 2011

вы можете использовать этот вариационный макрос для имитации printf, который записывает файл и номер строки с желаемым выходом.

#define eprintf(...) do {fprintf(stderr, "%s:%d: ", __FILE__, __LINE__);\
 fprintf(stderr, __VA_ARGS__);} while(0)

edit: модифицированный eprintf из предложений jcsalomon

1 голос
/ 19 января 2011

заменить ошибку на #define

что-то вроде:

#ifdef DEBUG
#define error(a,b) printf("Error at %s: %s\n", (a), (b))
#else
#define error(a,b) 
#endif

Вы также можете переместить AT в ошибку, вместо того, чтобы пропускать его каждый раз

1 голос
/ 19 января 2011
#ifdef DEBUG
#define ERROR(msg) error(AT, msg)
#else
#define ERROR(msg)
#endif

int main( int argc, char * argv[] )
{
   ERROR( "fake error");
   return 0;
}
...