【发布时间】:2020-01-04 02:52:36
【问题描述】:
我必须进行条件编译以在不使用某些代码时跳过它们。该项目是一个MCU项目,由LED、LCD、键盘等外部模块组成。
我有一个optimization.h 文件,用于告诉编译时使用了哪些模块。是这样的……
#ifndef OPTIMIZATION_H
#define OPTIMIZATION_H
// 1 - Compile code only for given modules
// 0 - Compile for all available modules
#define _OPTIMIZE_ 1
// Modules to compile
#define _LED_ 1
#define _SWITCH_ 1
// Modules not to compile
#define _LCD_ 0
#define _SSD_ 0
#endif
code.c 文件是这样的...
#include "optimization.h"
void myFun()
{
// Compile when LED is used or all modules are asked to use
// i.e when _OPTIMIZE_ is 0 or _LED_ is 1
// Need to compile this code
#if !(_OPTIMIZE_) || (_LED_)
/* My code goes here */
#endif
// Need to compile this code
#if !(_OPTIMIZE_) || (_SWITCH_)
/* My code goes here */
#endif
// Need not to compile
#if !(_OPTIMIZE_) || (_LCD_)
/* My code goes here */
#endif
// Need not to compile
#if !(_OPTIMIZE_) || (_SSD_)
/* My code goes here */
#endif
}
如果我只想使用 LED 和 SWITCH,则只需编译该部分代码。但是每次都会编译所有模块。可能是什么问题...
【问题讨论】:
-
Works For Me™。您是否打印了
OPTIMIZE和朋友以使他们符合您的期望?此外,good editor 将指示您未遵循哪些路径。 -
你(或我们)怎么知道它们被编译了?请生成minimal reproducible example
-
看起来它应该可以正常工作,除了 iirc,带有前导下划线的预处理器变量是为编译器保留的。可能会发生一些奇怪的定义冲突。您应该选择其他名称。您可以尝试使用
#if _VAR_ \n #error Var was true! \n #endif进行调试。此外,不需要#if指令中的括号。最后,您应该考虑一种完全不同的方法。将函数拆分为单独的文件并管理在 makefile 中编译的内容。从长远来看,这更清洁。 -
请注意,一般情况下,您不应创建以下划线开头的函数、变量、标记或宏名称。 C11 §7.1.3 Reserved identifiers 的一部分说: — 所有以下划线开头的标识符以及大写字母或另一个下划线始终保留供任何使用。 — 所有以下划线开头的标识符始终保留保留在普通和标记名称空间中用作具有文件范围的标识符。 另见What does double underscore (
__const) mean in C? -
不要相信 IDE 着色来进行调试/测试。如果您想知道是否编译了某些内容,请在其中写一个
#error Yes, it gets compiled!,它会清楚地告诉您。
标签: c microcontroller