我有一个定义列表:MASTER
,SLAVE0
,SLAVE1
,... SLAVE9
来控制将哪个音频数据阵列编程到微控制器中。 micro可以容纳不超过一个声音文件,所以我在main.c文件的顶部包含了以下定义:
#define MASTER
#define SLAVE0
#define SLAVE1
....
#define SLAVE9
然后,我在音频数组中写下以下内容:
#if defined(MASTER)
uint8_t sound[4096] PROGMEM = {127,126, ... }
#elif defined(SLAVE0)
uint8_t sound[4096] PROGMEM = {126,128, ... }
....
#else
#ERROR "One of MASTER-SLAVE9 must be defined!"
#endif
然后,希望编译的人必须通过并注释掉#define
行中的一行而且只有一行。这不仅乏味,而且容易出错。所以,我正在寻求简化流程。任何以下任务的指针都会有所帮助:
if defined(MASTER) && !(defined(SLAVE0) || defined(SLAVE1) ...)
需要11个这样的测试,每个测试有11个微妙的不同条件。这是一次性费用,但它有点难看。感觉这可能是一个共同的需求,并且应该有更好的方式。答案 0 :(得分:2)
您可以使用单个测试来确保只定义了一个宏。
#if (defined(MASTER) + defined(SLAVE1) + defined(SLAVE2)) != 1
#error "Too many macros defined"
#endif
对于定义本身,大多数编译器允许您使用命令行选项定义宏;这可能比具有“可配置选项列表”的文件更清晰。然后,您将能够创建多个构建配置,每个构建配置定义一个不同的宏,并按顺序构建它们(我不熟悉您的构建系统,以便能够解释您需要如何做到这一点)。 / p>
答案 1 :(得分:1)
我只是用所有可能的常量的名称做一个块注释,然后用一个定义来跟随它。谁想编译只是写他想要的东西。他第一次检查评论看清单,然后他就会写。
甚至更好,将此列表保留在注释中(供参考)并使用大多数编译器具有的-D选项(例如,-DMASTER定义master),如果您的工具支持它,请为每个位置进行构建配置你改变了-D值。使用不同的构建配置,我猜你也可以改变输出文件名,这样就可以用石头杀死两只鸟。
答案 2 :(得分:0)
为什么不能这样:
#define ARRAY_NAME (SLAVE0)
...
#if (ARRAY_NAME == MASTER)
// blah
#elif (ARRAY_NAME == SLAVE0)
// blah
// etc.
甚至更好,只是:
#define ARRAY_MASTER { 1, 2, 3, 4 }
#define ARRAY_SLAVE0 { 5, 6, 7, 8 }
// etc.
...
const uint8_t sound[] = ARRAY_MASTER;
答案 3 :(得分:0)
当您定义一个宏而不是一个宏时,您需要一条错误消息吗?好吧,只需写下:
#ifdef MASTER
uint8_t sound = { ... };
#endif
#ifdef SLAVE0
uint8_t sound = { ... };
#endif
#ifdef SLAVE1
uint8_t sound = { ... };
#endif
编译器会抱怨多次定义一个标识符。
为什么不用这个?
#define SLAVE <n>
uint8_t sound_master = { ... };
uint8_t sound_slave_0 = { ... };
uint8_t sound_slave_1 = { ... };
uint8_t sound_slave_2 = { ... };
#define XCAT(a,b) a##b
#define CAT(a,b) XCAT(a,b)
#ifdef SLAVE
#define sound CAT(sound_slave_,SLAVE)
#endif
#ifdef MASTER
#ifdef sound
/* warnin or so. but if you need an error just remove this ifdef **/
#endif
#define sound sound_master
#endif