Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable functions using MACROS

Tags:

c

function

macros

After searching quite a bit in the Internet for a solution I decided to ask here if my solution is fine.

I'm trying to write a simple and modular C logging library intended to be simple to disable and specially helping PhD students and researchers to debug an algorithm reducing as much as possibile the impact of the logging system.

My problem is that I want make possible for the user of the library to disable the logging system at compile time producing an executable in which the cost of the logger is 0.

The C code would look like this:

...
logger_t * logger;

result = logger_init(logger);
if(result == -1) {...}
...

this will simply initialize the logger. Looking for an example code I have checked the assert.h header but that soulution results in a list of warnings in my case. In fact, if logger_init() is substituted by 0 using the macro this will result in the variable logger never used.

For this reason I've decided to use this approach:

int logger_init(logger_t *logger);

#ifndef NLOG /* NLOG not defined -> enable logging */
int logger_init(logger_t *logger) {
...
}
#else  /* NLOG defined --> the logging system must be disabled */
#define logger_init(logger)     (int)((logger = NULL) == NULL)
#endif /* NLOG */

this does not result in warnings and I also avoid the overhead of calling the function. In fact my first try was to do like this:

int logger_init(logger_t *logger) {
  #ifndef NLOG /* NLOG not defined -> enable logging */
  ...
  #endif
  return 0;
}

keep calling the function even if I do not need it.

Do you think my solution could be considered a good solution? Is there a better solution?

Thanks a lot, guys! Cheers, Armando

like image 682
Armando Avatar asked Oct 10 '11 10:10

Armando


People also ask

Can macros be used for functions?

Macros are generally used to define constant values that are being used repeatedly in program. Macros can even accept arguments and such macros are known as function-like macros. It can be useful if tokens are concatenated into code to simplify some complex declarations.

How do I enable macros in CPP?

1.1 Enable and disable macros during compilationMSVC (Microsft Visual C++ compiler) uses '/' slash for defining macros from command line. I this case the macro can be defined using /DMACRO=VALUE. Build without setting any preprocessor directive. Build defining the LOGGING macro.


Video Answer


1 Answers

The standard idiom for that, at least in the 90s, was:

#ifndef NLOG
void logger_init(logger_t *logger);
void logger_log(logger_t *logger, ...);
#else
#define logger_init (void)sizeof
#define logger_log  (void)sizeof
#endif

Remember that sizeof operands are not evaluated, although they are syntax checked. This trick works also with variadic functions, because the sizeof operator will see an expresion with several comma operators:

logger_log(log, 1, 2, 3);

Converts to:

(void)sizeof(log, 1, 2, 3);

Those commas are not separating parameters (sizeof is not a function but an operator), but they are comma operators.

Note that I changed the return value from int to void. No real need for that, but the sizeof return would be mostly meaningless.

like image 142
rodrigo Avatar answered Sep 30 '22 17:09

rodrigo