简体   繁体   English

-Wincompatible-pointer-types和enum

[英]-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 not void* or short* ? 我可以修改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. 如果将enumint或两个不同的枚举相互混合,则它们的大小相同就可以了。 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.

相关问题 处理“-Wincompatible-pointer-types”警告 - Dealing with an `-Wincompatible-pointer-types` warning C [-Wincompatible-pointer-types] 如何转换 - C [-Wincompatible-pointer-types] how to cast 警告:C 中不兼容的指针类型 [-Wincompatible-pointer-types] - warning: incompatible pointer types [-Wincompatible-pointer-types] in C 警告:从不兼容的指针类型返回 [-Wincompatible-pointer-types]| - warning: return from incompatible pointer type [-Wincompatible-pointer-types]| 来自不兼容指针类型的赋值[Wincompatible-pointer-types] - Assignment from incompatible pointer type[Wincompatible-pointer-types] 编译时获取结构指针警告的 -Wincompatible-pointer-types - Getting -Wincompatible-pointer-types for struct pointer warning when compiling 来自不兼容的指针类型[-Wincompatible-pointer-types]的赋值 - assignment from incompatible pointer type [-Wincompatible-pointer-types] RecursiveFree函数-警告:从不兼容的指针类型[-Wincompatible-pointer-types]进行初始化 - RecursiveFree Function - Warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] 从不兼容的指针类型 [-Wincompatible-pointer-types] 传递“send_to_host”的参数 2 - passing argument 2 of ‘send_to_host’ from incompatible pointer type [-Wincompatible-pointer-types] C中的函数指针:警告:来自不兼容指针类型[-Wincompatible-pointer-types]的赋值 - Function pointers in C: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM