2011-01-21 51 views
1

我和IRC上的某個人討論過,這個問題出現了。本標準允許我們將int類型的對象改爲char左值。混疊規則是否對稱?

int a; 
char *b = (char*) &a; 
*b = 0; 

如果我們知道對齊是好的,我們會被允許在相反的方向做到這一點嗎?

我看到的問題是混淆規則不包括以下內容的簡單情況,如果考慮混疊規則作爲一種非對稱關係

int a; 
a = 0; 

的原因是,每個對象包含一系列sizeof(obj)unsigned char對象(稱爲「對象表示」)。如果我們更改int,我們將更改部分或全部這些對象。但是,別名規則只說明我們可以將int更改爲charunsigned char,但不能反過來。又如只有

int a[1]; 
int *ra = a; 
*ra = 0; 

一個方向由3.10/15(「一個聚集或聯合,其包括......型」)中描述,但此時,我們需要周圍的其他方法(「A類型是元素或聚合的非靜態數據成員類型...「)。

是否暗示了另一個方向?這個問題也適用於C.

+0

請問您可以添加一些代碼來說明您的意思是「相反的方向」嗎?你認爲哪些代碼可能不被允許? – 2011-01-21 14:05:01

+0

@Rob我以爲我展示了。也許我失敗了。 `a = 0`可能不被允許,以及`* ra = 0`。 「含有酒吧的酒吧」的「相反方向」是指「富含酒吧」。什麼是不明確的? – 2011-01-21 14:29:42

+0

如果你的意思是,`char a ='A'; int * pi =(int *)a; * pi ='B';`,那麼我不認爲這樣的事情一開始就是安全的。 – Nawaz 2011-01-21 15:02:07

回答

2

別名規則只是聲明對於內存中的任何給定對象有一個「有效類型」(C99 6.5.7,加上腳註73),並且對這樣的對象的任何訪問都經過一個的:

  • A型與有效類型(限定符如constrestrict,以及符號/無符號程度可以變化)
  • 結構或聯合包含一個這種類型
  • 一種字符類型兼容

有效類型沒有在高級中指定 - 當然這只是一個用於指定別名的構造。但意圖僅僅是,您不會訪問具有兩個不同非字符類型的同一對象。

所以答案是肯定的,你確實可以走向另一個方向。

1

標準(C99 6.3.2.3§7)定義了像這樣的指針轉換爲「很好」,轉換後的指針將指向相同的地址。 (除非CPU已經對齊使得不可能鑄造,那麼它是不確定的行爲。)

也就是說,實際的轉換本身沒有問題。如果您開始操作數據,會發生什麼......現在,這是另一個實現定義的故事。

下面是來自標準:

「A指向對象的指針或不完整的類型可被轉換成一個指針到一個不同的對象或不完整的類型。如果所得的指針沒有正確對齊(57),用於將尖-to類型,行爲是未定義的,否則,當再次轉換時,結果應與原始指針相等。

將指向對象的指針轉換爲指向字符類型的指針時,結果指向該對象的最低尋址字節。結果的連續增量,直到對象的大小,產生指針 到對象的其餘字節。「

」57)通常,'正確對齊'的概念是可傳遞的:如果指針到類型A正確對齊的指針類型B,這反過來正確對齊的指針類型C,然後指向類型A的指針 正確對齊指針類型C.「

0

我認爲我對這個問題有點困惑,但是第二個和第三個示例通過具有對象類型的左值訪問int(示例中爲int)。

C++ 3.10/15狀態,因爲它是第一項,它可以通過具有「對象的動態類型」類型的左值來訪問該對象。

我在這個問題上有什麼誤解?