我定义了这个结构:
struct Command_Type {
uint8_t A,B,Command;
}; // struct Command_Type
和一些常量,如:
#define _HeartBeat ((struct Command_Type) {0x10,0x01,0})
我确实在一些功能中使用了它,也可以按照我想做的方式使用它,但现在我想做一个开关功能,其中 case 应该使用标签。我在那里定义了一个 int_of_Command_Type :
#define int_of_Command_Type(A) ((unsigned int) (((int) ((A).A)) << 16) |\
(unsigned int) (((int) ((A).B)) << 8) | \
(unsigned int) (((int) ((A).Command))))
当我使用此函数从 struct Command_Type 类型的变量中打印出 %u 值时,它工作得很好。
现在我确实想做这样的事情:
struct Command_Type Command_type_var=_HearBeat;
....some code ....
switch(Command_type_var)
{
case inf_of_Command_Type(_HeartBeat): .....
break;
default:
};
我收到以下错误消息:case label does not reduce to an integer constant。有人知道我如何用简单的方法解决这个问题,因为我根本不明白当它适用于测试打印时有什么问题,只是在案例标签位置没有问题。我有很多已定义的命令,不想更改所有命令,但无论如何我不明白如何处理它。也许使用 (const int) 或需要什么?
希望任何人都能快速知道真正的问题是什么,以及是否有解决办法。
最佳答案
switch
语句的约束是,根据 C11 标准,它需要一个整数表达式::
6.8.4.2/1 The controlling expression of a switch statement shall have integer type.
Command_type_var
不匹配此约束,因为它是一个结构(即使该结构包含整数,即使您只包含整数位字段)。
如何解决:
这很简单:通过使用宏将您的结构转换为 switch 中的 int:
switch(int_of_Command_Type(Command_type_var)) // here we use an int
{
case int_of_Command_Type(_HeartBeat): // this is fortunately a constant
break;
default:
break;
};
当然,这只有在宏定义正确的情况下才有效:参数不能采用结构成员之一的名称,否则由于意外替换(A 参数应该改名为 X):
#define int_of_Command_Type(X) ((unsigned int) (((int) ((X).A)) << 16) |\
(unsigned int) (((int) ((X).B)) << 8) | \
(unsigned int) (((int) ((X).Command))))
编辑: 如果尽管 int_of_Command_Type(_HeartBeat)
可以在编译时计算,但您的编译器不会如果不将其识别为常量整数表达式,则应将开关替换为 if/else 序列。 MSVC 2015 就是这种情况,它似乎使用更严格的 6.6/6 规则,这些规则不需要实现来提供在结构常量上使用 .
运算符的可能性。
关于c - 我尝试通过创建一个 int 来切换一个特定的结构,但找不到错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35260588/