Lawrence Ironjuly
Lawrence Ironjuly

Reputation: 90

Are comparison between macro values bad in embedded programming?

I am building a program that needs to run on an ARM. The processor has plenty of resources to run the program, so this question is not directly related to this type of processor, but is related to non powerful ones, where resources and computing power are 'limited'.

To print debug informations (or even to activate portions of code) I am using a header file where I define macros that I set to true or false, like this:

#define DEBUG_ADCS_OBC true

and in the main program:

if (DEBUG_ADCS_OBC == true) {
    printf("O2A ");
    for (j = 0; j < 50; j++) {
        printf("%x ", buffer_obc[jj]);
    }
}

Is this a bad habit? Are there better ways to do this?

In addition, will having these IF checks affect performances in a measurable way?

Or is it safe to assume that when the code is compiled the IFs are somehow removed from the flow, as the comparison is made between two values that cannot change?

Upvotes: 0

Views: 227

Answers (5)

The optimizer will solve the extra resources problem as mentioned in the other replies, but I want to add another point. From the code readability point of view this code will be repeated a lot of times, so you can consider creating your specific printing macros. Those macros is what should be enclosed by the debug enable or disable macros.

#ifdef DEBUG_DCS_OBS
myCustomPrint    //your custom printing code
#else
myCustomPrint    //No code here
#end

Also this will decrease the probability of the macro to be forgotten in any file which will cause a real optimization problem.

Upvotes: 2

Clifford
Clifford

Reputation: 93476

The problem with getting the compiler to do this is the unnecessary run-time test of a constant expression. An optimising compiler will remove this, but equally it may issue warnings about constant expressions or when the macro is undefined, issue warnings about unreachable code.

It is not a matter of "bad in embedded programming", it bears little merit in any programming domain.

The following is the more usual idiom, will not include unreachable code in the final build and in an appropriately configured a syntax highlighting editor or IDE will generally show you which code sections are active and which are not.

#define DEBUG_ADCS_OBC

...

#if defined DEBUG_ADCS_OBC
    printf("O2A ");
    for (j = 0; j < 50; j++) 
    {
        printf("%x ", buffer_obc[jj]);
    }
#endif

Upvotes: 3

user694733
user694733

Reputation: 16043

I'll add one thing that didn't see being mentioned.

If optimizations are disabled on debug builds, and even if runtime performance impact is insignificant, code is still included. As a result debug builds are usually bigger than release builds.

If you have very limited memory, you can run into situation where release build fits in the device memory and debug build does not.

For this reason I prefer compile time #if over runtime if. I can keep the memory usage between debug and release builds closer to each other, and it's easier to keep using the debugger at the end of project.

Upvotes: 2

BDL
BDL

Reputation: 22167

The code you are using is evaluated everytime when your program reaches this line. Since every change of DEBUG_ADCS_OBC will require a recompile of your code, you should use #ifdef/#ifndef expressions instead. The advantage of them is, that they are only evaluated once at compile time.

Your code segment could look like the following:

Header:

//Remove this line if debugging should be disabled
#define DEBUG_DCS_OBS

Source:

#ifdef DEBUG_DCS_OBS

printf("O2A ");
for (j = 0; j < 50; j++) {
    printf("%x ", buffer_obc[jj]);
}

#endif

Upvotes: 4

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726509

Since the expression DEBUG_ADCS_OBC == true can be evaluated at compile time, optimizing compilers will figure out that the branch is either always taken or is always bypassed, and eliminate the condition altogether. Therefore, there is zero runtime cost to the expression when you use an optimized compiler.

If you are compiling with all optimization turned off, use conditional compilation instead. This will do the same thing an optimizing compiler does with a constant expression, but at the preprocessor stage. Hence the compiler will not "see" the conditional even with optimization turned off.

Note 1: Since DEBUG_ADCS_OBC has a meaning of boolean variable, use DEBUG_ADCS_OBC without == true for a somewhat cleaner look.

Note 2: Rather than defining the value in the body of your program, consider passing a value on the command line, for example -DDEBUG_ADCS_OBC=true. This lets you change the debug setting without modifying your source code, simply by manipulating the make file or one of its options.

Upvotes: 7

Related Questions