2016-05-12 29 views
2

通過以下經驗法則喜歡一切之前static_castdynamic_cast,我寫了下面的程序:爲什麼這是一個錯誤:的static_cast <unsigned*>(I)

int main(void) 
{ 
    int i = 0; 
    unsigned *j = static_cast<unsigned*>(&i); 
    return 0; 
} 

然而,它甚至不編譯:

$ g++ --std=c++11 test5.cpp 
test5.cpp: In function ‘int main()’: 
test5.cpp:4:44: error: invalid static_cast from type ‘int*’ to type ‘unsigned int*’ 
    unsigned *j = static_cast<unsigned*>(&i); 
              ^

爲什麼這是錯的?這種情況的正確表演是什麼?

+2

您需要'reinterpret_cast'。 – kennytm

+0

它也不會用'dynamic_cast'編譯,所以整個前提是有點欺騙性的。 –

+0

@kennytm,這就是我想要避免的 - 'reinterpret_cast'和'(unsigned *)'是邪惡的,我嘗試僅將它們用作最後​​的手段。我並不期望需要他們來完成這樣一項微不足道的任務。 – Vorac

回答

7

您可以將static_castint更改爲執行相應轉換的unsigned。但是你有什麼是一個指針;這個指針指向一個將被解釋爲int的內存區域。解引用指針會產生int的值。 static_cast will not convert between pointers to unrelated types

int i = 0; 
int* ip = &i; 
int j = *ip; // treat the region pointed to as an int 

爲了治療內存unsigned下提領,您需要重新解釋記憶;這就是reinterpret_cast所做的。

int i = 0; 
int* ip = &i; 
unsigned j = *reinterpret_cast<unsigned*>(ip); // treat the region pointed to as unsigned 

但是,您不應該這樣做。 reinterpret_cast的確如其所說:將內存重新解釋爲不同類型。如果位模式不符合該類型的預期結果,則結果將與static_cast<unsigned>執行的轉換不同。例如,在一個系統中,有符號整數不用二進制補碼錶示的情況就是這種情況。

正確的做法是取消引用int*然後static_cast<unsigned>的是,結果是:

int i = 0; 
int* ip = &i; 
unsigned j = static_cast<unsigned>(*ip); // treat the region pointed to as int 
             // then convert the int to unsigned 

總結:static_cast將執行整數轉換,但它不會重新解釋一個存儲器區域作爲不同的類型。這就是reinterpret_cast的用途。

2

你將不得不使用:

unsigned *j = static_cast<unsigned*>(static_cast<void*>(&i)); 

這是你可以在5點讀什麼here,或簡單地使用:reinterpret_cast

int i = 0; 
unsigned *j = reinterpret_cast<unsigned*>(&i); 

經常而是採用鑄-S程序員使用工會如下:

union { 
    int n; 
    unsigned char bt[4]; 
} data; 
data.n = i; 
data.bt[3] = 0xff; 

正如它在評論中說,使用uni對於鑄造而言是未定義的行爲 - 即使它受到大多數編譯器的支持:您可以在此處閱讀更多內容:Is using an union in place of a cast well defined?和這裏Is using an union in place of a cast well defined?

+2

聯合版本在C++中是未定義的行爲 –