2010-10-14 47 views
4

在C中使用restrict指針時,是否可以使用其初始值標識符更改變量?例如:在C中使用限制指針時,是否可以使用其初始標識符更改變量?

int foo = 0; 

int * restrict fooPtr = &foo; 
++(*fooPtr);     // Part 1: foo is 1 (OK) 

++foo;       // Part 2: foo is 2 (Is this OK?) 

int * fooPtr2 = &foo; 
++(*fooPtr2);     // Part 3: foo is 3 (BAD: You shouldn't access via a second pointer) 

...我的restrictfooPtr創建之後通過改變FOO的價值。

Part 1對我來說還行。我很困惑第2部分。並從我所瞭解的restrict,第3部分是不好的(編譯器允許它,但其行爲是不確定的,這取決於程序員不這樣做)。

回答

4

不,第2部分不好。

標準的具體部分是6.7.3.1/4。這部分內容非常密集,需要重新讀取一些內容,但是P是一個限制指針,X是它用來訪問和修改的對象。所以在你的例子中P是fooPtr而X是foo。然後:

用來訪問X的 值也應有其基於P.

「的基礎上」在上段的定義,並總結地址 每隔左值,左值foo確實不是具有基於限制指針P的地址。因此,當您通過自己的名稱訪問對象foo時規則中斷。

第3部分是不正常的完全一樣的原因,左值*fooPtr2沒有基於P要麼,但也可用於訪問X.

我說「不OK」 - 確切地說,該1 + 2的組合引起未定義的行爲,就像1 + 3的組合一樣。只要你實際上沒有通過限制指針訪問對象,限制「踢入」的定義都沒有。如果您想要刪除第1部分,請保留未使用的限制指針,然後2和3就可以了。

+0

非常感謝史蒂夫! :) – 2010-10-14 18:18:05

+0

你的意思是說,如果我們想通過它自己的名字和指針訪問X對象,我們可能會有錯誤? – 2010-10-14 18:23:39

+0

這個優化又是如何完成的? – 2010-10-14 18:25:12

1

是的,「第3部分」是未定義的行爲。從C99規範(6.7.3,第7段):

其通過 限制-合格音響編指針訪問的對象具有與指針 特殊關聯。 這個關聯定義在下面的6.7.3.1 中,要求對象直接使用或直接使用 的特定指針的值的所有訪問都使用 。

+0

太棒了。 「第2部分」如何?我解釋的方式是:「除了限制指針之外,不要通過任何其他方式訪問由限制指針指向的變量」。如果我的解釋是正確的,那麼這意味着我的例子中的「第2部分」會很糟糕。 – 2010-10-14 18:10:10

1

我會說#2是壞的。例如,編譯器可能會通過將* fooPtr中的值加載到寄存器中進行優化,然後再將該寄存器值寫回到foo中 - 在您的++ foo之後,以致++ foo丟失。

1

假設所有你的問題的部分發生在相同的塊,這不是行訪問的foo直接(第2部分),也不經由另一個指針來訪問它的值(第3部分):

  • 6.7.3.1正式定義

用來訪問X的值每隔左值也應具有基於P.

其地址限制

restrict的正式定義是相當困難的遵循(至少對我來說),但下面不那麼正式的描述也從標準概括起來相當不錯(至少在這種情況下):

通過限制合格指針訪問的對象與該指針有一個特殊的關聯 。這個關聯定義在下面的6.7.3.1中,要求對該對象的所有訪問直接或間接使用該特定指針的值。

+0

謝謝Michael!很有幫助! – 2010-10-14 18:18:48

相關問題