C语言 如果枚举值不正确,则在编译时触发错误

q9yhzks0  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(141)

我想知道如果多个enum的值是坏的,我是否可以触发#error

enum config_choice {
  YES,
  NO
};

enum config_choice PARAM_1 = YES;
enum config_choice PARAM_2 = NO;
enum config_choice PARAM_3 = YES;

....

字符串
例如我想要像这样的东西

if(PARAM_1 == YES && (PARAM_2 == YES || PARAM_3 == YES)   ){
    #error "Bad configuration!!!"
}


枚举值在运行时永远不会更改。

qnakjoqk

qnakjoqk1#

  • 编辑:适应C11/C23:*

从C11开始,static_assert支持此功能-在即将到来的C23之前,您需要
#include <assert.h> for,因为它只是一个将其Map到_Static_assert的宏(您也可以应用它,但C23会弃用前者,这使得前者也成为关键字)。
但是,你需要 * 编译时间常量 *(和下面的老式变体一样),所以你需要:

#define PARAM_1 YES
#define PARAM_2 NO
#define PARAM_3 YES

字符串
(谢谢@StoryTeller的提示。

  • 老式(C11前)变体:*

这类事情本身是不被支持的--但是你仍然可以通过使用一个小技巧来实现编译中断:创建或定义一个负大小的数组!
这可以看起来如下(一般情况):

typedef int StaticCheck[-(theFailureCondition)];
// or:
typedef int StaticCheck[-!(theSuccessCondition)];


举个具体的例子:

enum config_choice
{
  YES,
  NO
};

// though you need compile time constants for (!):
#define PARAM_1 YES
#define PARAM_2 NO
#define PARAM_3 YES
// enum config_choice PARAM_X = ...;
// is not; not even if you apply const to:
// enum config_choice const PARAM_Y = ...;

typedef int ConfigCheck[-(PARAM_1 == YES && (PARAM_2 == YES || PARAM_3 == YES))];


这会导致编译失败(您的目标),当然,产生的错误消息是非常不幸的。
如果你需要很多这样的检查,你可以创建一个宏,例如。

#define STATIC_ASSERT(CONDITION) \
    typedef int CONCAT(StaticCheck_, __LINE__)[-!(CONDITION)]
// note the naming: we want to  a s s e r t, thus want to fail on opposite value
#define CONCAT(X, Y) CONCAT_(X, Y) // classic token concatenation...
#define CONCAT_(X, Y) X ## Y


当然,您不能在同一行中定义多个测试,但无论如何都不推荐这样做(甚至更难阅读的错误消息)。
针对您的具体情况:

STATIC_ASSERT(PARAM_1 != YES || (PARAM_2 != YES && PARAM_3 != YES));
// (inverted condition, see above)


godbolt上的演示(使用宏)。

相关问题