[英]-Wincompatible-pointer-types and enum
从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);
}
但是他们太多了。
您自己的带有静态函数的建议听起来还不错。
我可以修改
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);
}
枚举常量 (即您的枚举声明中的值的列表)保证为int
类型。 但是,这不适用于enum
变量本身。 一个enum
不必与int
兼容,也不必与另一个不同的enum
类型变量兼容。 大小因情况而异,因编译器而异。
这是问题的根源。 如果将enum
和int
或两个不同的枚举相互混合,则它们的大小相同就可以了。 然后它们是兼容的,您可以毫无问题地将指针从一种类型转换为另一种类型。
但是,如果它们的大小不同,则无法执行此操作。 它将提供不兼容的类型:您将违反严格的别名规则,并且还可能存在对齐问题。 再加上显而易见的一点:如果您尝试从仅存储一小块数据的位置读取大块数据,则不会告诉您最终的结果。
可靠的解决方案是将函数更改为仅使用整数类型而不是指针:
int BEncAsnIntContent (BUF_TYPE b, int data);
似乎没有理由让它们首先通过指针传递参数。 把事情简单化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.