2013-05-21 46 views
4

我有一個關於C中的指針表示的問題,如果我有正確理解本款C11標準:指針表示

C11(N1570),第6.2.5.28,類型,P。 36

同樣,指向兼容類型的合格或不合格版本的指針應具有相同的表示和對齊要求。

我推斷,類型int *int const *具有相同的代表,但不是類型int **int const **。我對嗎 ?

如果是這樣,我想知道爲什麼這兩種類型在第二種情況下沒有相同的表示形式?我的意思是,intint const具有相同的表示形式,同爲int *int const *,因此int **int const **有什麼問題?

+0

你爲什麼認爲'int **'和'int const **'有不同的表示? –

+0

因爲標準說「指向合格或不合格版本的兼容類型的指針」,並且,如果我正確地理解,在int **和int const **的情況下,它們不是指向兼容類型的指針'int *'和'int const *'不兼容)。 – Taurre

+0

這是正確的,它們不能保證具有相同的表示形式,因爲指針可以是指向常量內存或動態分配內存或任何其他內容的指針。我誤解了,並認爲你說的指針本身是一個不同的表示:\ –

回答

1

正如Bart van Ingen Schenau所說,我認爲標準化委員會希望儘可能少地限制指針的表示。從編譯器的角度來看,對int *int const *有一個明確的表示是有用的,因爲常量可以放在更大或更小的存儲器中,因此可以使用更小的指針指向更小的存儲器。然而,這意味着%s格式說明符printf應該有兩個版本,一個用於常量字符串,另一個用於非常量字符串。這會破壞很多遺留的代碼,我的猜測是標準化委員會缺乏勇氣來強化社區。大概是這樣的。由於沒有令人信服的理由對int **int const **執行相同的表示法,所以他們就這樣離開了。然而,對這些指針使用不同的表示方式幾乎沒有用處,除了可能用於某些角落案例應用程序。

他們也可能已決定只有char *char const *應該有相同的表示,只是爲了節省%s,但也許有一些需要指向其他基本類型以及平等一些其他接口。

類似地,它在某些系統上對於全局內存中的東西,堆棧中的東西以及堆中的東西具有不同的指針表示。然而,在C中可能會使用一個指針,使得它可能包含這樣的指針(同樣可以考慮可變參數),因此它至少需要一個可以表示所有指針的指針表示。

在C內存空間的Embedded-C擴展中,引入了明確允許程序員從不同的數據總線獲取數據,而不需要可以表示它們的指針類型。這樣的存儲空間也可以用來爲常量,堆等指定專用存儲器。因此允許更高效的指針表示。

我的一位同事也提到K & R原型或更好的原型,仍然是允許的。在這種情況下,編譯器無法檢測參數聲明和使用之間的表示差異。這無疑會導致遺留軟件中許多未被發現的問題。這些問題可以通過要求在參數傳遞(包括可變參數)上使用通用表示法來解決,例如在varag中爲floatdouble完成,但這也會損害不同表示的預期效率。

+0

感謝您的回覆,她完美地回答了我的問題。 – Taurre

1

您是正確的int *int const *需要使用相同的表示和int **int const **沒有這種要求。

不需要相同表示的原因很可能避免對奇怪的體系結構的C編譯器造成不必要的限制,同時使C的規範不再難於理解。

請注意,有一些實現方式,例如,char*int*具有不同的大小。這可能導致了一個基本假設,即指向不同類型的指針可以具有不同的表示,然後對指向兼容類型和指向結構/聯合的指針的基本規則進行異常處理。

據我所知,除了DS9K的編譯器之外,沒有實現可以利用int **int const **的這個餘地。

+0

感謝您的回覆。 「不需要相同表示的原因最有可能避免對奇怪的體系結構的C編譯器造成不必要的限制」嗯...是的,但是對指針強加一個特定表示要求而不是指針指針不一致?我的意思是,除了明確的理由,沒有具體的理由證明這種「歧視」是合理的嗎? – Taurre

+0

@BartvanIngenSchenau感謝您的信息。你有沒有機會知道一個'struct {char x; }'在這些類型的機器上有'char *'-like或'int *'-like指針格式? – glglgl