[英]-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.