2017-09-03 123 views
3

讓我們假設我有以下代碼:指向對象表示元素的指針或指向提供的存儲元素的指針?

int* p = new (new unsigned char[3*sizeof(int)]) int{}; 
unsigned char* b = reinterpret_cast<unsigned char*>(p); 
auto b2 = b + 2*sizeof(int);//it is UB if compilers do not assume that 
          //b is pointer to an unsigned char[3*sizeof(int)] 
int* p2 = new (b2) int{}; 

如果b不是指針到3*sizeof(int)無符號字符的陣列,對於*p提供存儲,則段[expr.add]作爲C++標準意味着b+2*sizeof(int)是未定義的行爲(UB)。否則,如果編譯器必須假定b也是指向爲*p提供存儲的無符號字符數組的指針,那麼它不是UB。

所以它在標準中指定的編譯器必須假定b是一個指針,它指向的*p提供存儲unsigned char[3*sizeof(int)]

回答

1

根據[expr.static.cast]:

類型的「指針CV1空隙」 A prvalue可以轉換爲類型「指針CV2 T」的prvalue,其中T是一個 對象類型和cv2與cv1具有相同的cv資格,或者具有更高的cv資格。如果原始的 指針值表示存儲器中的字節的地址A並且A不滿足T的對齊要求 ,則未指定所產生的指針值。否則,如果原始指針值指向一個 對象a,並且存在一個類型爲T(忽略cv-qualification)的對象b,該對象可以與a進行指針互換(6.9.2) ,則結果是指向b的指針。否則,轉換指針值不變。

根據[expr.reinterpret.cast]:

一個目的指針可以被明確地轉換成不同類型的對象的指針。當一個 對象指針類型的prvalue v被轉換爲對象指針類型「指向cv T的指針」時,結果爲static_cast(static_cast(v))。

所以我會假設b指向三個無符號字符數組的一個元素。