Why only define a macro if it's not already defined?

CMacrosC PreprocessorIfndef

C Problem Overview


All across our C code base, I see every macro defined the following way:

#ifndef BEEPTRIM_PITCH_RATE_DEGPS
#define BEEPTRIM_PITCH_RATE_DEGPS					0.2f
#endif

#ifndef BEEPTRIM_ROLL_RATE_DEGPS
#define BEEPTRIM_ROLL_RATE_DEGPS					0.2f
#endif

#ifndef FORCETRIMRELEASE_HOLD_TIME_MS
#define FORCETRIMRELEASE_HOLD_TIME_MS				1000.0f
#endif

#ifndef TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS
#define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS		50.0f
#endif

What is the rationale of doing these define checks instead of just defining the macros?

#define BEEPTRIM_PITCH_RATE_DEGPS					0.2f
#define BEEPTRIM_ROLL_RATE_DEGPS					0.2f
#define FORCETRIMRELEASE_HOLD_TIME_MS				1000.0f
#define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS		50.0f

I can't find this practice explained anywhere on the web.

C Solutions


Solution 1 - C

This allows you to override the macros when you're compiling:

gcc -DMACRONAME=value

The definitions in the header file are used as defaults.

Solution 2 - C

As I said in the comment, imagine this situation:

foo.h

#define FOO  4

defs.h

#ifndef FOO
#define FOO 6
#endif

#ifndef BAR
#define BAR 4
#endif

bar.c

#include "foo.h"
#include "defs.h"

#include <stdio.h>

int main(void)
{
	printf("%d%d", FOO, BAR);
	return 0;
}

Will print 44.

However, if the conditional ifndef was not there, the result would be compilation warnings of MACRO redefinition and it will print 64.

$ gcc -o bar bar.c
In file included from bar.c:2:0:
defs.h:1:0: warning: "FOO" redefined [enabled by default]
 #define FOO 6
 ^
In file included from bar.c:1:0:
foo.h:1:0: note: this is the location of the previous definition
 #define FOO 4
 ^

Solution 3 - C

I do not know the context but this can be used to give the user the availability to override the values set by those macro definitions. If the user explicitly defines a different value for any of those macros it will be used instead of the values used here.

For instance in g++ you can use the -D flag during compilation to pass a value to a macro.

Solution 4 - C

This is done so that the user of the header file can override the definitions from his/her code or from compiler's -D flag.

Solution 5 - C

Any C project resides on multiple source files. When working on a single source file the checks seem to (and actually) have no point, but when working on a large C project, it's a good practice to check for existing defines before defining a constant. The idea is simple: you need the constant in that specific source file, but it may have been already defined in another.

Solution 6 - C

You could think about a framework/library that gives to the user a default preset that allow the user to compile and work on it. Those defines are spreaded in different files and the final user is advised to include it's config.h file where he can config its values. If the user forgot some define the system can continue to work because of the preset.

Solution 7 - C

Using

#ifndef BEEPTRIM_PITCH_RATE_DEGPS
#define BEEPTRIM_PITCH_RATE_DEGPS                   0.2f
#endif

allows the user to define the value of the macro using the command line argument (in gcc/clang/VS) -DBEEPTRIM_PITCH_RATE_DEGPS=0.3f.

There is another important reason. It is an error to re-define a preprocessor macro differently. See this answer to another SO question. Without the #ifndef check, the compiler should produce an error if -DBEEPTRIM_PITCH_RATE_DEGPS=0.3f is used as a command line argument in the compiler invocation.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTrevor HickeyView Question on Stackoverflow
Solution 1 - CBarmarView Answer on Stackoverflow
Solution 2 - CEnzo FerberView Answer on Stackoverflow
Solution 3 - CIvaylo StrandjevView Answer on Stackoverflow
Solution 4 - Cuser3458View Answer on Stackoverflow
Solution 5 - CGeorgeView Answer on Stackoverflow
Solution 6 - CLPsView Answer on Stackoverflow
Solution 7 - CR SahuView Answer on Stackoverflow