5 回答
TA貢獻1773條經驗 獲得超3個贊
這是嚴格的別名規則,可以在C ++ 03標準的3.10節中找到(其他答案提供了很好的解釋,但沒有提供規則本身):
如果程序試圖通過不同于以下類型之一的左值訪問對象的存儲值,則行為未定義:
對象的動態類型,
一個cv限定版本的動態類型的對象,
與對象的動態類型對應的有符號或無符號類型的類型,
一種類型,是有符號或無符號類型,對應于對象動態類型的cv限定版本,
一種聚合或聯合類型,包括其成員中的上述類型之一(包括遞歸地,子聚合或包含聯合的成員),
一個類型,它是對象動態類型的(可能是cv限定的)基類類型,
a
char或unsigned char類型。
C ++ 11和C ++ 14措辭(強調變化):
如果程序試圖通過以下類型之一以外的glvalue訪問對象的存儲值,則行為未定義:
對象的動態類型,
一個cv限定版本的動態類型的對象,
與對象的動態類型類似的類型(如4.4中所定義),
與對象的動態類型對應的有符號或無符號類型的類型,
一種類型,是有符號或無符號類型,對應于對象動態類型的cv限定版本,
聚合或聯合類型,包括其元素或非靜態數據成員中的上述類型之一(遞歸地,包括子聚合或包含聯合的元素或非靜態數據成員),
一個類型,它是對象動態類型的(可能是cv限定的)基類類型,
a
char或unsigned char類型。
兩個變化很?。?em>glvalue而不是lvalue,以及聚合/聯合案例的澄清。
第三個變化提供了更強有力的保證(放寬強混疊規則):類似類型的新概念現在可以安全別名。
另外,?措詞(C99; ISO / IEC 9899:1999 6.5 / 7;完全相同的措詞在ISO / IEC 9899中使用:2011§6.5?7):
對象的存儲值只能由具有以下類型之一(73)或88)的左值表達式訪問:
與對象的有效類型兼容的類型,
與對象的有效類型兼容的類型的限定版本,
與對象的有效類型對應的有符號或無符號類型的類型,
與有效類型的對象的限定版本對應的有符號或無符號類型的類型,
聚合或聯合類型,包括其成員中的上述類型之一(包括遞歸地,子聚合或包含聯合的成員),或者
一個字符類型。
73)或88)此列表的目的是指定對象可能或可能不具有別名的情況。
TA貢獻1946條經驗 獲得超4個贊
作為Doug T.已經寫過的補充,這里有一個簡單的測試用例,可能用gcc觸發它:
check.c
#include <stdio.h>void check(short *h,long *k){
*h=5;
*k=6;
if (*h == 5)
printf("strict aliasing problem\n");}int main(void){
long k[1];
check((short *)k,k);
return 0;}編譯gcc -O2 -o check check.c。通常(我嘗試過的大多數gcc版本)都輸出“嚴格別名問題”,因為編譯器假定“h”不能與“check”函數中的“k”相同。因此,編譯器優化了if (*h == 5)遠離并始終調用printf。
對于那些感興趣的人是x64匯編程序代碼,由gcc 4.6.3生成,在ubuntu 12.04.2 for x64上運行:
movw $5, (%rdi)movq $6, (%rsi)movl $.LC0, %edi jmp puts
所以if條件完全從匯編代碼中消失了。
- 5 回答
- 0 關注
- 935 瀏覽
添加回答
舉報
