[英]-Wincompatible-pointer-types and enum
Implicit cast from short*
to int*
prints the warning about incompatible pointer type (and I understand why). 从short*
隐式转换为int*
显示有关不兼容的指针类型的警告(我理解原因)。
Implicit cast from enum*
to int*
prints same warnig. 从enum*
隐式转换为int*
打印相同的警告。
There's a tool snacc
that generates the following code: 有一个工具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));
...
}
A header file shipped with this tool: 该工具附带的头文件:
int BEncAsnIntContent (BUF_TYPE b, int *data);
#define BEncAsnEnumContent BEncAsnIntContent
The call to BEncChargedPartyContent
prints the warning. 调用BEncChargedPartyContent
将显示警告。
Can I modify the declaration of BEncAsnEnumContent
so it accepts without a warning pointers to any enum, but not void*
or short*
? 我可以修改BEncAsnEnumContent
的声明,使其接受没有任何警告的指针,但指向任何枚举的指针,但不能为void*
或short*
吗?
Of course using sed
I could replace the macro BEncChargedPartyContent
with a static function: 当然,使用sed
可以用静态函数替换宏BEncChargedPartyContent
:
static AsnLen BEncChargedPartyContent (BUF_TYPE b, ChargedParty *data)
{
return BEncAsnEnumContent(b, (int*)data);
}
But there're too many of them. 但是他们太多了。
Your own proposal with a static function sounds not so bad. 您自己的带有静态函数的建议听起来还不错。
Can I modify the declaration of
BEncAsnEnumContent
so it accepts without a warning pointers to any enum, but notvoid*
orshort*
? 我可以修改BEncAsnEnumContent
的声明,使其接受没有任何警告的指针,但指向任何枚举的指针,但不能为void*
或short*
吗?
If you want, you can use a static assertion as John Zwinck hinted at. 如果需要,可以使用John Zwinck提示的静态断言。
#define BEncAsnEnumContent(b, d) ({\
_Static_assert(sizeof(int) == sizeof *(d), "wrong data size");\
BEncAsnIntContent(b, (int *)d); })
What you think of in your comment below is a viable alternative with the advantage that it allows enumerations of different sizes; 您在下面的评论中所想到的是一种可行的选择,其优点在于它允许枚举不同的大小; this is how I understand what you mean: 这是我如何理解您的意思:
#define BEncAsnEnumContent(b, d) MyEncAsnEnumContent(b, *(d))
static int MyEncAsnEnumContent(BUF_TYPE b, int val)
{
return BEncAsnIntContent(b, &val);
}
The enumeration constants , that is the list of values in your enum declaration, are guaranteed to be of type int
. 枚举常量 (即您的枚举声明中的值的列表)保证为int
类型。 However, this does not apply to the enum
variable itself. 但是,这不适用于enum
变量本身。 An enum
need not be compatible with int
nor with another, different enum
type variable. 一个enum
不必与int
兼容,也不必与另一个不同的enum
类型变量兼容。 The size can vary from case to case and from compiler to compiler. 大小因情况而异,因编译器而异。
This is the root of the problem. 这是问题的根源。 If you mix enum
and int
, or two different enums with each other, all is fine if they have the same size. 如果将enum
和int
或两个不同的枚举相互混合,则它们的大小相同就可以了。 They are then compatible and you can convert pointers from one of the types to the other without problems. 然后它们是兼容的,您可以毫无问题地将指针从一种类型转换为另一种类型。
However, if they are not of the same size, you cannot do this. 但是,如果它们的大小不同,则无法执行此操作。 It would give incompatible types: you would violate the strict aliasing rule and there might also be alignment issues. 它将提供不兼容的类型:您将违反严格的别名规则,并且还可能存在对齐问题。 Plus the obvious: if you try to read a large chunk of data from a location where only a small chunk of data is stored, there's no telling what you will end up with. 再加上显而易见的一点:如果您尝试从仅存储一小块数据的位置读取大块数据,则不会告诉您最终的结果。
The reliable solution is to change your function to simply use an integer type instead of a pointer: 可靠的解决方案是将函数更改为仅使用整数类型而不是指针:
int BEncAsnIntContent (BUF_TYPE b, int data);
There doesn't seem to be a reason why they pass the parameter through a pointer in the first place. 似乎没有理由让它们首先通过指针传递参数。 Keep it simple. 把事情简单化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.