C preprocessor macro replacing #if #else statements - c

I'm using this statement now to switch between small and slightly more extensive error messages in my C code:
#ifdef COMPACTC
error_code ((uint16_t) init_cascade, 5);
#else
error_message (__func__, "cascades malloc failed");
#endif
(it's part of an embedded C code library, so I often don't have the memory available to store the error message strings).
In the first case (COMPACTC defined) I output only a function address and and error number. In the second case I output the full function name and a human-readable error message.
Since I'm copying this snippet all over my code now, I hope I can replace it with a single macro, which I can use like this:
error (init_cascade, "cascades malloc failed", 5)
and provides the correct C code depending on COMPACTC being defined or not.
Maybe it's even possible to have the current function (or some unique identifier) automatically derived from the current location, though I think the preprocessor doesn't know which function's scope it's currently in.
Another improvement would be if a unique error code (5 in this case, which is based on the return value) could be automatically generated from the error message (like a hash value or something).
Then the macro call could be as simple as this:
error ("cascades malloc failed")
Of course, when using hashes, I would need some sort of reference (file/comment) to its original message.
Context: error messages on AVR 8-bits MCU
About the context of this question: This code is written for the ATmega168 (having only 2k of RAM), and AFAIK there's no good/recent emulator available for Linux. So I'm trying to find a good way to produce error messages/codes without the strings eating all of my memory.
Alternative: C function?
A completely different, probably more flexible solution would be to define a C function error (function, message, code) and move the #if/#else/#endif construction to its body.
I'm not sure though whether a string literal is compiled in by gcc if it is referred to in a function call but never used inside the function body.
Edit: I just tested this idea: using a string literal in a call but not in the body still has it added to the executable by gcc, so this "alternative" doesn't seem to work.

This should actually be fairly easy:
#ifdef COMPACTC
# define COMBINED_ERROR(function, message, size) error_code((uint16_t)function, size)
#else
# define COMBINED_ERROR(function, message, size) error_message (__func__, message)
#endif
and now you can write:
COMBINED_ERROR(init_cascade, "cascades malloc failed", 5);

For the first part I suggest:
#ifdef COMPACTC
# define error(par1, ...) error_code((uint16_t)par1, __VA_ARGS__)
#else
# define error(par1, ...) error_message (__func__, par1, __VA_ARGS__)
#endif
With this solution you can define as many params as you like.
For the second requirements consider to use macro to insert specific code. Consider the following macro:
#define CallWithError(fnc, ...) { \
int RetCode = fnc(__VA_ARGS__); \
if (RetCode) \
error(init_cascade, "cascades malloc failed", RetCode); \
}
In this case you can use the macro to call the function foo and automatically generate error:
CallWithError(foo, 1, "hello");
This will expand in:
{
int RetCode = foo(1, "hello");
if (RetCode)
error(init_cascade, "cascades malloc failed", RetCode);
}

Related

A way around defining new variables in function calls

I have a function dangerous(GEN x) which is called frequently in my code, where GEN is a typedef. For debugging purposes, I would like to add checkSafe to all instances of this function, something like
#ifdef DEBUG
#define dangerous(x) GEN __x = (x); if(checkSafe(__x)) dangerous(__x)
#endif
but I'm concerned that this might not work as intended. What's the right way to do something like this? The function is used too often to instrument each use individually and it is not desirable to check outside debug mode (for various reasons).
Things to be aware of / careful about:
Using a macro and a function with the same name at the same time. While it can produce valid C, you'll have to 1) take extra precautions to avoid unwanted expansion (either always define the function before the macro, or enclose the function name in parentheses at definition time) and 2) double check that every use of the function also includes your instrumenting code.
Solution: rename the original function into something like _dangerous.
Using the macro in various situations:
in an if with a single statement: if (foo) dangerous(x);
around an else from the parent if: if (foo) dangerous(x); else bar();
when leaking variables into the parent namespace can break things: GEN __x = 5; dangerous(__x);.
Solution: enclose the macro in a construct like do { ... } while(0).
You must take into account any side effects at copy time, like resource allocation or CPU intensive operations (since GEN is a typedef, this is likely not a concern).
Lastly, you may also want to complain when checkSafe fails, e.g. by logging an error message, or even aborting the program.
Putting the above together, you would instrument the function like this:
#ifdef DEBUG
#define dangerous(x) do { \
GEN __x = (x); \
if (checkSafe(__x)) \
_dangerous(__x); \
else \
complainAbout(__x); \
} while(0)
#else
#define dangerous _dangerous
#endif
If dangerous() returns a value (e.g. int) that you want to use.
Solution: Define a function to instrument your original function and pass the return value up:
#ifdef DEBUG
static inline int dangerous(GEN x) {
if (checkSafe(x))
return _dangerous(x);
complainAbout(x);
return ERROR_CODE;
}
#else
#define dangerous _dangerous
#endif

What are the benefits to using a debug macro rather than a simple function?

It seems that for printf-style debugging people always use preprocessor macros. Is there anything wrong with a solution similar to this one?
void debug(char *msg) {
#ifdef DEBUG
printf("%s", msg);
#endif
}
Usually so that they can do something like this:
#define DEBUG(MSG) printf("[%s:%i] %s\n", __FILE__, __LINE__, (MSG))
Since it's so useful to have the exact source of a debug message right there in the log, this is a pretty common pattern. But if you used a function, like so:
void DEBUG(const char *MSG) {
printf("[%s:%i] %s\n", __FILE__, __LINE__, (MSG));
}
Then you'd only ever get to see the filename and line number corresponding to the printf() call in DEBUG(), and never those of the code that called DEBUG().
1) Your code will break if msg is %d or such, because printf expects a format string. printf("%s", msg); is better.
2) Not really. Macros are overused unless you're micro-optimizing (e.g. for code size). Functions are easier to debug with since you can do stuff like stop in debug in your debugger. There's a zillion other things that are tricky with macros. See http://www.brainbell.com/tutors/c/Advice_and_Warnings_for_C/Macros_and_Miscellaneous_Pitfalls.html
3) As #Jonathan Grynspan pointed out - the macro form is easier to use with FILE , LINE . In my opinion developers like taking shortcuts in typing that make their code harder to maintain for others later, and ironically harder to debug themselves later. Best practice IMO: type extra, make your code easy to debug and easy to run in a debugger, and use a function with signature debug(const char* msg, const char* FILE_LOC, unsigned LINE_NUMBER)
If one uses a DEBUG macro, then changing a single #define statement or compilation option and recompiling can make all of the debug code vanish from the executable. By contrast, if one uses a DEBUG() function, then every invocation will generate code to call the function, whether or not the function itself does anything.
As well as the use of __FILE__, __LINE__, you should also compare the following:
#ifdef NDEBUG
#define DEBUG_PRINT(...) ((void)0)
#else
#define DEBUG_PRINT(...) printf(__VA_ARGS__)
#endif
Against your function:
void debug(const char* msg) {
#ifndef NDEBUG
printf("%s", msg);
#endif
}
With the macro, I can write:
DEBUG_PRINT("Expected %d, got %d\n", correct_value, result);
With the function, I have to go to some effort to construct one or more strings using my integers, and call the function one or more times. In release mode the function does nothing, so the string is unused. The optimizer might manage to eliminate the code to construct it, or then again it might not. With the macro there's no doubt.
That said, you could write your debug function to do the right thing with varargs. But your function as written will hit this problem eventually, and you'll have to add a debugf.

Macro to turn off printf statements

What MACRO can be used to switch off printf statements, rather than removing them all for deployment builds, I just want to switch them off, skip them, ignore them.
EDIT: I personally use gcc, but code is part of a larger project which will be compiled on a Panda board running Ubuntu.
Not exactly what you ask for, but I use this construct in my code for debug output when I do not have a proper logging system handy:
#if 1
#define SPAM(a) printf a
#else
#define SPAM(a) (void)0
#endif
So I can do this all over my code
SPAM(("foo: %d\n", 42));
and then disable all of them by changing 1 to 0 in #if above.
But if you have variadic macro support in all compilers that you write code for, then you may go for other answers and just redefine printf. (That being said, I find it useful to distinct debugging prints from regular ones in code — using a different function name helps readability.)
Note that you also can redirect stdout to the /dev/null, but I assume that you want to get rid from runtime overhead as well.
#ifdef IGNORE_PRINTF
#define printf(fmt, ...) (0)
#endif
See also C #define macro for debug printing which discusses some important issues closely related to this.
Two options, either:
#define printf(...)
(requires C99 variadic macro parameters), you need to put it in some common header file which is never included before stdio.h, if there is one..
Or you can tell the linker to link it to something else, in GCC you would define
int wrap_printf(void) {return 0;}
and link using
--wrap printf
All that said, you should probably not be using printf for printing debug output, but rather a macro or utility function (which in turn can use printf if you'd like) which you have better control over.
Hope that helps.
If you want to avoid the potential warning that Jonathan's answer may give you and if you don't mind an empty call to printf you could also do something like
#define printf(...) printf("")
This works because C macros are not recursive. The expanded printf("") will just be left as such.
Another variant (since you are using gcc) would be something like
inline int ignore_printf(char const*, ...)
__attribute__ ((format (printf, 1, 2)));
inline int ignore_printf(char const*, ...) { return 0; }
#define printf ignore_printf
and in one compilation unit
int ignore_printf(char const*, ...)
I use to prefix the debug printf()s (not all of them) with PDEB.
For the debug builds, I compile with -DPDEB= (nothing)
For the release builds, I compile with -DPDEB="0&&" or -DPDEB="0 && "
That way, the following code (test.c):
#include <stdio.h>
void main(void) {
printf("normal print\n");
PDEB printf("debug print\n");
}
outputs:
either (in release mode):
normal print
either (in debug mode):
normal print
debug print
Ideally, one could aim for turning the PDEB into the "//" (comments mark), except that this is not possible under the standard pre-/processing chain.
Another possibility would be something like freopen("/dev/null", "w", stdout);
This doesn't exactly disable printf though -- it's roughly equivalent to running your program with stdout redirected to /dev/null, like: ./myprog > /dev/null at the shell prompt.
I included #define printf // in common header file. It will suppress all the printf.
Below simple function serves the purpose, I use the same.
int printf(const char *fmt, ...)
{
return (0)
}
Use this macro to enable or disable the printf.
//Uncomment the following line to enable the printf function.
//#define ENABLE_PRINTF
#ifdef ENABLE_PRINTF
#define DEBUG_PRINTF(f,...) printf(f,##__VA_ARGS__)
#else
#define DEBUG_PRINTF(f,...)
#endif
Then call "DEBUG_PRINTF" instead of "printf".
For example:
DEBUG_PRINTF("Hello world: %d", whateverCount);
I have used two macros for this. The first one defines the condition to print. In this simple example we print any time the parameter is not zero. More complex expressions can be used.
The second one determines, based on the first macro, to call or not printf.
If the condition can be determined by the compiler (with the right optimization settings) no code is generated.
If the condition cannot be determined at compile time then will be at run time. One of the advantages of this method is that if printf is not going to happen then the whole printf is not evaluated avoiding many conversions to string that can happen in a complex printf statement.
#define need_to_print(flag) ((flag) != 0))
#define my_printf(debug_level, ...) \
({ \
if(need_to_print(debug_level)) \
printf(__VA_ARGS__); \
})
to use it call my_printf instead of printf and add a parameter at the beginning for the print condition.
my_printf(0, "value = %d\n", vv); //this will not print
my_printf(1, "value = %d\n", vv); //this will print
my_printf(print_debug, "value = %d\n", vv); //this will print if print_debug != 0
the ( ... ) parenthesis surrounding the macro make it a single statement.

How to know what function called another

I wanna know if there is any way to know where the function currently in execution was called, this is, in what file and line.
I'm using C language, and I'm looking for something similar to __FUNCTION__, __LINE__ or __FILE__ macros.
Rename your function
void Function(param1)
{
}
to
void Function_debug(param1, char * file, char * func, unsigned long line)
{
}
Then #define a macro like this:
#define Function(param1) Function_debug(param1, __FILE__, __FUNCTION__, __LINE__)
There's nothing in C itself that would give you this information. You could either trace the information yourself (upon entry/exit) or rely on platform specific APIs to walk the call stack and determine the calling function, but not much more.
__FILE__, __LINE__ etc are preprocessor macros which can easily be expanded to the correct value at compile time. A function may get called from many possible places, so that can't be done via the preprocessor. Finding out the caller's name would be very difficult; it involves walking the stack and matching addresses to symbols.
If you can live with a small hack, this might work (untested):
/* Add a called argument to your function */
void _myFunction(char *caller, int more_args)
/* And define a macro that adds it automagically */
#define myFunction(a) _myFunction(__FUNCTION__, a)
There isn't anything that is supported in all implementations that will do what you want. I have occasionally found myself in the same situation, where I needed to track callers for a few methods and did something like the following:
#ifdef TRACKBACK
int foo(int arg1, int arg2, const char * file, int line)
{
SEND_TO_LOG("foo", file, line);
#else
int foo(int arg1, int arg2)
{
#endif
...
...
Of course, it makes for a bit of a headache at the calling end, so you'll want to do something like:
#ifdef TRACKBACK
#define TRACKING, __FILE__, __LINE__
#else
#define TRACKING
#endif
Then the call:
foo(arg1, arg2 TRACKING); //note the lack of the comma
It does the trick when all else fails.
If you need to know it at runtime, I don't think it's possible.
If you need to know it at debugtime, you can place a breakpoint on the function you want, and then, using GDB (using bt command) or Vistual Studio's debugger, inspect the current STACK TRACE.
This is actually a bit more complicated to do. Your best bet is to get a backtrace on a debugger, or find something similar to pstack for your platform. The manual way would involve traversing the call stack and using debug symbols to translate that to files and lines.
You can use logs .
#define BEGIN_FUNC(X,Y,Z) printf("Function %s Entered at line %d from file %s",X,Z,Y)
#define END_FUNC(X) printf("Function %s Exited at line %d from file %s",X,Z,Y)
foo()
{
BEGIN_FUNC(__func__,__FILE__,__LINE__);
//Your code here
END_FUNC(__func___FILE__,__LINE__);
}
OR
Use bt in gdb. I call it backtrace.

#define LOG_MSG(...) for debugging

How does the following code work?
#define ENABLE_DEBUG 1
#if ENABLE_DEBUG
#define LOG_MSG printf
#else
#define LOG_MSG(...)
#endif
Depending on the value of ENABLE_DEBUG, LOG_MSG is either defined to be an alias for printf() or it is defined as a no-op macro. It is implied that you can change the value to 0 to disable debugging. This is a common technique for making it easy to switch between debugging builds which display lots of output and release builds which are quiet.
#define LOG_MSG printf
This makes it an alias for printf().
#define LOG_MSG(...) /* empty */
And this defines it as an empty macro. Notice that here it has a set of parentheses, which means the macro takes parameters. It has nothing afterwards which means it expands to absolutely nothing. And the ... indicates that this macro can take a varying number of arguments. This syntax is a C99 extension so it may not be available on older C compilers.
LOG_MSG("file not found\n");
The result is that a LOG_MSG() call will either print a message or do nothing depending on whether logging is enabled.
// If ENABLE_DEBUG is non-zero, a debugging printout:
printf("file not found\n");
// If ENABLE_DEBUG is zero, an empty statement:
;
For what it's worth, whoever authored this macro could've done a better job by replacing the first definition with one using the ... syntax (which he/she is clearly familiar with), printing to stderr instead of stdout:
#define LOG_MSG(...) fprintf(stderr, __VA_ARGS__)
This uses the preprocessor to change code before compilation.
If ENABLE_DEBUG is defined as 1, whenever the preprocessor sees
LOG_MSG("something happened");
It will replace it with
printf("something happened");
If it is defined as 0, or not defined it will replace it with nothing (as the other answer that has just been published says).

Resources