[英]Is C++17 implementable on big-endian platforms?
讓我們看下面的代碼:
int i = 10;
char c = reinterpret_cast<char&>(i);
[expr.reinterpret.cast] / 11 :
如果可以使用reinterpret_cast將類型“指向T1的指針”顯式轉換為類型“指向T2的指針”,則可以將類型T1的glvalue表達式強制轉換為“對T2的引用”類型。 結果指向與源glvalue相同的對象,但是具有指定的類型。
因此,具有指定char
類型的reinterpret_cast<char&>(i)
左值引用了int
對象i
。
要初始化c
,我們需要取值,因此應用了從左值到右值的轉換[conv.lval] /3.4 :
glvalue指示的對象中包含的值是prvalue結果。
L2R轉換的結果是i
對象中包含的值。 只要i
的值在char
可以表示的范圍內( [expr] / 4表示否則為UB),則應將變量c
初始化為具有相同的值。
從實現POV來看,在小端平台上,可以通過讀取i
對象地址處的字節來輕松實現。 但是,在大端平台上,編譯器將必須添加偏移量以獲取最低有效字節。 或者,將整個int
對象讀入寄存器並屏蔽第一個字節,這在兩個字節序上都是可以接受的。
如果你認為上面的程序可以由編譯器容易處理,以產生所要求的C ++標准17碼運行得代碼,認為把指針轉換的int
指向i
到一個指針char
。 這種強制轉換不會更改指針值,即它仍然指向int
對象i
,這意味着在通過以下L2R轉換將間接操作符應用於此類指針時,其行為應如上所述,即獲取int
對象的值如果可以用char
類型表示。
在下面的代碼中
int i = 10;
f(reinterpret_cast<char*>(&i)); // void f(char*)
如果編譯器不知道函數f
用其參數做什么,編譯器是否應該將i
的地址調整一些偏移量? 而且編譯器也不知道什么將傳遞給函數f
。 上面的代碼和函數f
在不同的翻譯單元中。
例如,如果f
取消引用指針以通過它讀取值,則它將獲得i
的值,如上所述。 但是它也可以使用指向真實char
對象的指針來調用,因此f
無法調整給定的指針。 這意味着調用方應調整指針。 但是,如果[basic.types] / 3允許, f
傳遞指向memcpy
的指針以將sizeof(int)
個字節復制到此大小的字符數組並返回到另一個int
對象,該怎么辦? 很難想象如何在此處調整指針以達到所需的行為( [basic.types] / 3和[conv.lval] /3.4 )。
那么,如果現有的實現確實符合C ++ 17標准,那么現有的實現又會做什么呢?
編輯:完全重寫:您已經使我確信該標准已被破壞。
...結果指向與源glvalue相同的對象,但具有指定的類型。
glvalue指示的對象中包含的值是prvalue結果。
我同意直譯可能會得出您得出的結論。
根據您的解釋, reinterpret_cast
(以及根據reinterpret_cast
定義的任何內容)變得無用,不僅在BE系統上,而且在LE系統上,都無法實現(考慮非整數類型和char
之間的重新解釋)。 因此,我不認為這是預期的含義。 這可以被認為是缺陷報告的候選者。
造成混淆的原因可能是由於對“值包含於” , “所指示的對象”和“結果引用相同的對象”等表達式的定義不夠准確。 闡明或重新措辭其中一些或全部可能是有條理的。
[intro.object] / 1說,對於非多態對象,“在其中找到的值的解釋取決於用於訪問它們的表達式的類型(Clause [expr])”。
(重點是標准本身,而不是我的)
如您所見,這種情況下的表達式類型為char
,因此編譯器無需將此值解釋為int
類型的某些對象的值。
但是,在大端平台上,編譯器將必須添加偏移量以獲取最低有效字節。 或者,將整個int對象讀入寄存器並屏蔽第一個字節,這在兩個字節序上都是可以接受的。
僅當您傳遞i
的值時,這才是正確的。 但是,使用reinterpret_cast<char&>
,傳遞的是地址,因為引用只是指針的語法不同。 因此,只要sizeof(int) > 1
, c
將獲得i
的MSB值,該值為0
。
您寫的與以下內容沒有區別:
int i = 10;
char c = *reinterpret_cast<char*>(&i);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.