dereferencing type-punned pointer will break strict-aliasing rules
最近遇到了一個(gè)編譯告警,嚴(yán)格別名和類(lèi)型雙關(guān),整理一下相關(guān)的材料。
strict aliasing
以下問(wèn)題摘自1
I have the following questions:
And yes, I actually need this kind of aliasing.
The strict aliasing rule makes this setup illegal, two unrelated types can’t point to the same memory. char * are defined as being able to alias anything, only char* / unsigned char* has this privilege.
aliasing assumptions
這個(gè)告警只有在 strict aliasing optimization 開(kāi)啟的情況下才會(huì)出現(xiàn),gcc 在 -O2 優(yōu)化會(huì)開(kāi)啟上述優(yōu)化2,因此會(huì)出現(xiàn)該告警,忽略該告警有可能產(chǎn)生錯(cuò)誤代碼。出現(xiàn)該告警的原因是編譯器為了優(yōu)化代碼,做了一個(gè)假設(shè),即指針不會(huì)有其他類(lèi)型的別名, (char *) 例外,意思是兩個(gè)類(lèi)型不同的指針不會(huì)指向同一塊內(nèi)存。當(dāng)然這個(gè)特性孰好孰壞我們這里暫不討論,實(shí)際上爭(zhēng)議還是比較大的3。
Aliasing rules simply say that you can only access an object through its own type, its signed / unsigned variant type, or through a character type (signed char, unsigned char).
如何解決
如題主所問(wèn),如果我們確實(shí)需要做指針強(qiáng)制類(lèi)型轉(zhuǎn)換,怎樣才能解決這個(gè)告警并得到健壯的代碼呢?
C/C++ 是非常貼近硬件底層的語(yǔ)言,指針為我們編程提供了很大的便利性,同時(shí)也引入了一些隱患。我們可以很方便地重新解析一塊內(nèi)存上的數(shù)據(jù)(reinterpret) ,隱患是相伴便利性而生的,有時(shí)指針類(lèi)型強(qiáng)轉(zhuǎn)并不安全,例如出現(xiàn)未初始化字節(jié)數(shù)據(jù)的問(wèn)題。
我們可以采用以下做法來(lái)消除這個(gè)告警:
- 采用 __attribute__((__may_alias__)) 屬性去提示編譯器對(duì)某個(gè)變量關(guān)閉上面提到的假設(shè)。
- 關(guān)閉這個(gè)假設(shè), -fno-strict-aliasing,可能影響優(yōu)化,linux kernel 有大量的指針操作,其構(gòu)建帶這個(gè)選項(xiàng)。
- 屏蔽這個(gè)告警,-Wno-strict-aliasing,很不推薦!有掩耳盜鈴之嫌!
- 使用 union 來(lái)解決,這也是 gcc 推薦的做法。type punning via unions feels natural。
https://stackoverflow.com/questions/4163126/dereferencing-type-punned-pointer-will-break-strict-aliasing-rules-warning/4163223 ??
https://gcc.gnu.org/onlinedocs/gcc-7.5.0/gcc/Optimize-Options.html#Optimize-Options ??
https://lkml.org/lkml/2018/6/5/769 ??
總結(jié)
以上是生活随笔為你收集整理的dereferencing type-punned pointer will break strict-aliasing rules的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 精密光学测量3-光栅曝光精密光路搭建
- 下一篇: 世界坐标系/相机坐标系/图像坐标系 转换