2012-11-14 60 views
0

C++標準提到reinterpret_cast是定義執行,並沒有給出任何保證不同的是澆鑄背面(使用reinterpret_cast)到原始類型將導致傳遞給第一原始值。reinterpret_cast和c-style cast是否兼容(通過C++標準)?

至少某些類型的C風格轉型的行爲方式非常相似 - 使用相同的值來回轉換結果 - 目前我正在使用枚舉和int s,但也有一些其他示例。

雖然C++標準給出了兩個鑄風格的定義,它也給混合管型相同的質量保證?如果庫X從函數int Y()中返回一些enum的值,可以使用上述任何一種類型,而不必擔心在Y的身體中將初始enum轉換爲int的投射是什麼?我沒有X的源代碼,所以我無法檢查(無論如何,它可能會隨着下一個版本發生變化),文檔中幾乎沒有提到類似的東西。

我知道,在在這樣的情況下,兩個大多數實現投射相同的行爲;我的問題是:C++標準對這種情況有什麼看法 - 如果有的話。

+0

Ç鑄造來回並不總是導致相同的值...'(浮動)((INT)3.141)'不會給我'3.141 '回來。 – Xymostech

+0

您可以使用'static_cast'在ints和enums之間進行轉換。 –

+0

@Xymostech我的意思是隻有在C風格演員下才能正常工作的類型。我知道在某些情況下C風格的鑄造會改變數值,但對於這些情況,整個問題都是沒有意義的。 –

回答

4

C++根據static_cast,const_castreinterpret_cast定義了C語言轉換語法的語義。所以,無論使用哪種語法來實現它,您都可以獲得相同的操作保證。

2

reinterpret_cast只能用於特定的轉化:

  • 指針(足夠大的)整數,而反向
  • 函數指針爲一個函數指針
  • 對象指針爲一個對象指針
  • 指針到成員指針
  • 左值表達爲參考

加(有條件地)函數指針對象的指針和反向。在大多數情況下,轉換後的值是未指定的,但有保證轉換後跟隨其後的轉換將產生原始值。

特別是,您不能使用reinterpret_cast在整數和枚舉類型之間進行轉換;必須使用static_cast(或隱式地將非範圍枚舉轉換爲整數類型時)完成轉換,該轉換爲足夠大的整數類型定義良好。唯一可能的問題是,如果庫中沒有的東西完全瘋狂如return reinterpret_cast<int&>(some_enum);

A C樣式轉換將執行無論是static_castreinterpret_cast,隨後const_cast,都是必要的;所以任何由static_cast定義明確的轉換也可以通過C風格演員明確定義。

1

不,reinterpret_cast不是相當於C風格演員。 C風格轉換允許在reinterpret_cast中不允許拋出const volatile(因此它包含const_cast的功能)。如果在源和目標類型之間允許static_cast,它將執行與reinterpret_cast具有不同語義的static_cast。它不允許轉換,它將回退到reinterpret_cast。最後還有一個角色案例,其中C cast不能用任何其他類型轉換表示:它忽略了訪問說明符。

那說明差異的一些例子:

class b0 { int a; }; 
class b1 { int b; }; 
class b2 { int c; }; 
class d : public b0, public b1, b2 {}; 
int main() { 
    d x; 
    assert(static_cast<b1*>(&x) == (b1*)&x); 
    assert(reinterpret_cast<b1*>(&x) != (b1*)&x); // Different value 
    assert(reinterpret_cast<b2*>(&x) != (b2*)&x); // Different value, 
                // cannot be done with static_cast 
    const d *p = &x; 
    // reinterpret_cast<b0*>(p);     // Error cannot cast const away 
    (b0*)p;           // C style can 
} 
+0

還有'const_cast',所以你註釋掉的錯誤可以使用它「修復」。無論如何,我認爲你誤會了我。我的問題不是如果這些可以在給定的代碼行中進行交換,而是如果通過其中的一種(例如C風格)將值轉換爲另一種類型,則在使用另一種類型轉換爲原始類型時保證賦予相同的值(任何'_cast' C++運算符)。 –

+0

@j_kubik:我理解了這個問題,也許我在答案中不清楚。 'reinterpret_cast'是**不等同於C cast,也不等同於'static_cast'或'const_cast'。在它們相等的情況下,可以應用反演,在其他一些情況下,反演也可以是隱式的,但是**不能盲目地爲我提供的示例盲目地執行reinterpret_cast'(特別是第二個這個問題:*我可以退後一步忽略原始演員是什麼嗎?*答案是**否,你不能** –

+0

如果我知道一些不透明的libX之間鑄造的原始類型和流行類型,那麼我知道他們使用了什麼類型的演員:C風格以可預測的方式工作,並且你上面提到的限制了他們使用'_cast'強制轉換的自由,通常只剩下一個選項(只在leas之一,在指針之間可以'reinterpret_cast'是可能的但通常只有在static_cast不可用的情況下才會使用)清除後,我想知道是否可以在不知道以上哪兩個被使用的情況下回退。已知類型 –