从short*
到int*
的隐式强制转换打印出有关不兼容指针类型的警告(我理解为什么)。
从enum*
到int*
的隐式广播会打印相同的警告。
有一个工具snacc
可生成以下代码:
typedef enum
{
CHARGINGCALLING = 0,
CHARGINGCALLED = 1,
NONECHARGING = 2
} ChargedParty; /* ENUMERATED { CHARGINGCALLING (0), CHARGINGCALLED (1), NONECHARGING (2) } */
typedef struct MSOriginatingSMSinSMS_IWMSC /* SET */
{
ChargedParty* chargedParty; /* [6] IMPLICIT ChargedParty OPTIONAL */
} MSOriginatingSMSinSMS_IWMSC;
#define BEncChargedPartyContent BEncAsnEnumContent
int BEncMSOriginatingSMSinSMS_IWMSCContent (BUF_TYPE b, MSOriginatingSMSinSMS_IWMSC *v) {
BEncChargedPartyContent (b, (v->chargedParty));
...
}
此工具附带的标头文件:
int BEncAsnIntContent (BUF_TYPE b, int *data);
#define BEncAsnEnumContent BEncAsnIntContent
对BEncChargedPartyContent
的调用会打印警告。
我是否可以修改BEncAsnEnumContent
的声明,使其在没有任何枚举的警告提示的情况下接受,但不是void*
或short*
?
当然使用sed
我可以用静态函数替换宏BEncChargedPartyContent
:
static AsnLen BEncChargedPartyContent (BUF_TYPE b, ChargedParty *data)
{
return BEncAsnEnumContent(b, (int*)data);
}
但是它们太多了。
答案 0 :(得分:0)
你自己的静态功能建议听起来并不那么糟糕。
我可以修改
BEncAsnEnumContent
的声明吗? 接受没有警告指针任何枚举,但不是void*
或short*
?
如果需要,可以使用John Zwinck暗示的静态断言。
#define BEncAsnEnumContent(b, d) ({\
_Static_assert(sizeof(int) == sizeof *(d), "wrong data size");\
BEncAsnIntContent(b, (int *)d); })
您在下面的评论中所提到的是一种可行的替代方案,其优势在于它允许不同大小的枚举;这就是我理解你的意思:
#define BEncAsnEnumContent(b, d) MyEncAsnEnumContent(b, *(d))
static int MyEncAsnEnumContent(BUF_TYPE b, int val)
{
return BEncAsnIntContent(b, &val);
}
答案 1 :(得分:0)
枚举常量,即枚举声明中的值列表,保证为int
类型。但是,这不适用于enum
变量本身。 enum
不需要与int
兼容,也不能与另一个不同的enum
类型变量兼容。大小可能因情况而异,也可能因编译器而异。
这是问题的根源。如果您将enum
和int
或两个不同的枚举相互混合,如果它们具有相同的大小,则一切正常。然后它们是兼容的,您可以将指针从其中一种类型转换为另一种类型而不会出现问题。
但是,如果它们的大小不同,则无法执行此操作。它会提供不兼容的类型:您会违反严格的别名规则,也可能存在对齐问题。另外显而易见的是:如果你试图从只存储一小部分数据的位置读取大量数据,那么就不知道你最终会得到什么。
可靠的解决方案是将您的函数更改为仅使用整数类型而不是指针:
int BEncAsnIntContent (BUF_TYPE b, int data);
似乎并不是他们首先通过指针传递参数的原因。保持简单。