簡體   English   中英

C ++ 17可在大端平台上實現嗎?

[英]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) > 1c將獲得i的MSB值,該值為0

您寫的與以下內容沒有區別:

int i = 10;
char c = *reinterpret_cast<char*>(&i);

暫無
暫無

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

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