30

I want to create log.c file with containing info(), debug() and error() functions. These functions are working without printing file name, line number,..etc. So when I call one of this function I want to dump the file name, line number, and function name of the caller. So how do we exactly trace back? Is there a way to trace back on C or, if we use macros, how can this be done?

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
sura2k
  • 7,365
  • 13
  • 61
  • 80

2 Answers2

50

I'd pass the data to the function through parameters (maybe get the help of a macro)

int info(const char *fname, int lineno, const char *fxname, ...) { /* ... */ }
int debug(const char *fname, int lineno, const char *fxname, ...) { /* ... */ }
int error(const char *fname, int lineno, const char *fxname, ...) { /* ... */ }

And to call them

info(__FILE__, __LINE__, __func__, ...);
debug(__FILE__, __LINE__, __func__, ...);
error(__FILE__, __LINE__, __func__, ...);

Note: __func__ is C99; gcc, in mode C89 has __FUNCTION__

pmg
  • 106,608
  • 13
  • 126
  • 198
  • Is there a way to to create these kind of functions, without passing __FILE__,..etc parameters all the time? – sura2k Jan 17 '12 at 11:10
  • 11
    Yes, with a macro. For instance, for C99 (which has variadic macros): `#define INFO(...) info(__FILE__, __LINE__, __func__, __VA_ARGS__)` – pmg Jan 17 '12 at 11:20
  • i m using same function #define INFO(...) info(__FILE__, __LINE__, __func__, __VA_ARGS__) in cpp but it giving me errors when i include same header file from different classes ? do you know how i can implement same in C++. – SourabhKus Dec 21 '16 at 08:22
12

If you use macros, I believe you can make this work by using __FILE__, __LINE__, and __FUNCTION__. For example,

#define INFO(msg) \
    fprintf(stderr, "info: %s:%d: ", __FILE__, __LINE__); \
    fprintf(stderr, "%s", msg);

You could use functions too, but you would need to pass in __FILE__, etc. to make sure they had the correct value.

Michael
  • 880
  • 2
  • 6
  • 16
  • 2
    `gcc -std=gnu99` says `__LINE__` is an integer and warns about casting it to `char *`. Shouldn't the second line be `fprintf(stderr, "info: %s:%d: ", __FILE__, __LINE__); \ ` (`%s` replaced by `%d`)? – matec Feb 13 '14 at 18:15
  • Fixed! Leaking some old-school Python there. – Michael Feb 13 '14 at 21:05