C 使用if语句进行编译时配置

C 使用if语句进行编译时配置,c,gcc,embedded,C,Gcc,Embedded,在嵌入式C世界中,我们经常将配置细节存储在头文件中,以便为特定任务构建库,从而最小化开销和编译大小 一个例子是: //libnameConf.h #define LIBNAME_WAVE LIBNAME_A typedef enum { LIBNAME_A, LIBNAME_B, LIBNAME_C } libname_wave_t; 对于这种特殊情况,我们使用了一个if语句,编译器显然会崩溃,这是一件好事,因为我们只需要对coef_arr_a的引用,这样其他语句就不会被编译成

在嵌入式C世界中,我们经常将配置细节存储在头文件中,以便为特定任务构建库,从而最小化开销和编译大小

一个例子是:

//libnameConf.h
#define LIBNAME_WAVE LIBNAME_A

typedef enum {
  LIBNAME_A,
  LIBNAME_B,
  LIBNAME_C
} libname_wave_t;

对于这种特殊情况,我们使用了一个if语句,编译器显然会崩溃,这是一件好事,因为我们只需要对coef_arr_a的引用,这样其他语句就不会被编译成二进制文件并占用空间

不幸的是,这产生了警告

warning: comparison between 'enum <anonymous>' and 'enum <anonymous>' [-Wenum-compare]
警告:“enum”和“enum”之间的比较[-Wenum-compare]

是否有更好的方法避免此警告?

是否仅使用宏而不使用变量和枚举

//libnameConf.h
#define LIBNAME_A
// #define LIBNAME_B // Uncomment this line and both comment the above line while changing libs.
然后我们使用几个条件编译语句,如下所示

//libname.c
double coef_arr_a[100] = {...};
double coef_arr_b[100] = {...};

#ifdef LIBNAME_A
  somestruct.waveCoefs = coef_arr_a;
  //do other coef_arr_a specific stuff
#endif
#ifdef LIBNAME_B
  somestruct.waveCoefs = coef_arr_b;
#endif

听起来你需要C语言,但是你的方式不正确。条件编译是在编译器之前运行的一个概念。预处理器的作用是在将源代码提供给编译器之前对其进行操作。因为您没有使用任何预处理器条件,所以所有源代码都会被提供给编译器,而不管编译时条件如何。必须使用预处理器条件来减少二进制数。

为枚举提供名称?为了清晰起见,编辑了枚举。有一个名称在警告中并没有什么区别。我并不建议使用预处理器或宏,但对于这样的事情,它确实是最常见的,并且一定会在编译时进行评估。编译器不需要计算或优化
if
语句,即使一个好的编译器可能会这样做。特别是,编译器实际上不需要省略非执行分支的代码。在正常情况下,我同意依靠编译器来摆脱你不打算运行的代码是次优的。但在这种情况下,我们可以通过查看生成的映射文件和/或当您试图将一个巨大的.elf加载到一个微小的Cortex M0上时,看到JTAG探针发狂来证明这一点。我还应该提到,执行这种优化的宏有点凌乱,但这比代码的原始版本更主观
enum
缺少终止的
但我从一个简单的更新实现(MSVC)中没有得到任何警告或错误。维基百科上有一个参考。我们可以搜索主题“C预处理器”。正如该页所说,我们可以使用更复杂的条件编译语句来满足我们的需求:使用#ifdef xxx…#elif defined xxx#恩迪夫
//libname.c
double coef_arr_a[100] = {...};
double coef_arr_b[100] = {...};

#ifdef LIBNAME_A
  somestruct.waveCoefs = coef_arr_a;
  //do other coef_arr_a specific stuff
#endif
#ifdef LIBNAME_B
  somestruct.waveCoefs = coef_arr_b;
#endif