为什么只定义一个macros,如果它还没有定义?

在我们的C代码基础上,我看到每个macros定义如下:

#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 

做这些定义检查的基本原理是什么,而不是仅仅定义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 

我无法在networking上的任何地方find这种做法。

这使您可以在编译时覆盖macros:

 gcc -DMACRONAME=value 

头文件中的定义被用作默认值。

正如我在评论中所说的,想象一下这种情况:

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; } 

将打印44

但是,如果ifndef条件不存在,则结果将是MACRO重定义的编译警告,它将打印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 ^ 

我不知道上下文,但是这可以用来给用户提供覆盖这些macros定义所设置的值的可用性。 如果用户明确地为这些macros定义了一个不同的值,它将被用来代替这里使用的值。

例如,在g ++中,可以在编译过程中使用-D标志将值传递给macros。

这样做是为了使头文件的用户可以覆盖他/她的代码或编译器的-D标志中的定义。

任何C项目驻留在多个源文件。 在处理单个源文件时,检查似乎(实际上)没有意义,但在处理大型C项目时,最好在定义常量之前检查现有的定义。 这个想法很简单:在特定的源文件中需要常量,但可能已经在另一个文件中定义了。

你可以考虑一个框架/库,给用户一个默认的预设,允许用户编译和处理它。 这些定义在不同的文件中被传播,并且最终的用户被build议包含它的config.h文件,在那里他可以configuration它的值。 如果用户忘记了一些定义,系统可以继续工作,因为预设。

运用

 #ifndef BEEPTRIM_PITCH_RATE_DEGPS #define BEEPTRIM_PITCH_RATE_DEGPS 0.2f #endif 

允许用户使用命令行参数(在gcc / clang / VS) -DBEEPTRIM_PITCH_RATE_DEGPS=0.3f来定义macros的值。

还有一个重要的原因。 重新定义不同的预处理器macros是错误的。 看到这个答案另一个SO问题 。 没有#ifndef检查,如果在编译器调用中使用-DBEEPTRIM_PITCH_RATE_DEGPS=0.3f作为命令行参数,编译器应该会产生一个错误。