簡體   English   中英

C中的嚴格別名

[英]strict aliasing in C

關於類型雙關語的問題:為什么這段代碼會破壞嚴格的別名規則:

int main()
{
    int a = 1;
    short j;

    printf("%i\n", j = *((short*)&a));
    return 0;
}

這不是:

int main()
{
    int a = 1;
    short j;
    int *p; 

    p=&a;
    printf("%i\n", j = *((short*)p));
    return 0;
}

通過gcc -fstrict-aliasing構建。

謝謝!

他們都違反了嚴格的別名規則 ,我將在這里引用我的答案強調我的前進 ):

代碼違反了嚴格的別名規則 ,這使得通過不同類型的指針訪問對象是非法的 ,盡管允許通過char *進行訪問。 允許編譯器假設不同類型的指針不指向相同的存儲器並相應地進行優化。

gcc是在小的documetation更詳細-Wstrict-aliasing=n 這里它說:

此選項僅在-fstrict-aliasing處於活動狀態時處於活動狀態。 它會警告可能會破壞編譯器用於優化的嚴格別名規則的代碼。 更高的級別對應於更高的准確性(更少的誤報) 更高的級別也相應於更多的努力,類似於-O的工作方式。 -Wstrict-aliasing相當於-Wstrict-aliasing = 3。

並描述每個級別如下:

  • 1級:最具攻擊性,快速,最不准確。 當更高級別沒有警告但-fstrict-aliasing仍然會破壞代碼時可能很有用,因為它幾乎沒有錯誤的否定。 但是,它有許多誤報。 警告可能不兼容的類型之間的所有指針轉換,即使從未解除引用。 僅在前端運行。

  • 等級2:積極,快速,不太精確。 可能仍有許多誤報(盡管不是1級),也沒有假陰性(但可能超過1級)。 與級別1不同,它僅在發出地址時發出警告。 警告不完整的類型。 僅在前端運行。

  • 級別3(-Wstrict-aliasing的默認值):應該具有非常少的誤報和很少的誤報。 啟用優化后,比級別1或2略慢。 在前端處理常見的pun + dereference模式: *(int*)&some_float 如果啟用了優化,它也會在后端運行,它使用流敏感點來處理多個語句案例。 僅在取消引用轉換后的指針時發出警告。 不警告不完整的類型。

因此不能保證捕獲所有實例,不同級別具有不同程度的准確性。

通常,您正在尋找的效果可以通過聯合使用類型懲罰來完成,我在上面的鏈接答案中介紹了gcc明確支持

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM