Bei Verwendung eines beschränken Pointer in C, ist es OK, um eine Variable mit seinem ursprünglichen Identifier zu ändern?

StackOverflow https://stackoverflow.com/questions/3936060

  •  30-09-2019
  •  | 
  •  

Frage

Wenn Sie eine restrict Pointer in C verwendet, ist es OK, um die Variable mit seinem ursprünglichen Identifier zu ändern? Zum Beispiel:

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)

... änderte ich den Wert von foo durch foo nach dem restrict fooPtr erstellt wurde.

Teil 1 sieht nicht gut aus für mich. Ich bin verwirrt über Teil 2 . Und von dem, was ich über restrict verstehen, Teil 3 ist schlecht (Compiler ermöglicht es, aber sein Verhalten ist nicht definiert, und es ist für den Programmierer bis das nicht zu tun).

War es hilfreich?

Lösung

Nein, Teil 2 ist nicht in Ordnung.

Der spezifische Teil der Norm ist 6.7.3.1/4. Dieser Abschnitt ist recht dicht und nimmt ein paar Wieder liest, aber P ist ein Zeiger beschränken, und X ist ein Objekt es für den Zugriff verwendet wird, und welche modifiziert wird. So in Ihrem Beispiel P ist fooPtr und X foo. Dann gilt:

  

Jeder anderer L-Wert verwendet, die für den Zugriff auf   Wert von X wird auch seine Adresse   basierend auf P.

„auf Basis von“ im vorhergehenden Absatz definiert ist, und zusammenfassen, die lvalue foo tut nicht hat seine Adresse basierend auf dem Zeiger P. So beschränkt die Regel gebrochen wird, wenn Sie auf das Objekt zugreifen foo durch seinen eigenen Namen.

Teil 3 ist nicht OK für genau den gleichen Grund, die L-Wert *fooPtr2 basiert nicht auf P entweder, sondern auch dem Zugriff auf X verwendet wird.

Ich sage „nicht in Ordnung“ - um genau zu sein, die Kombination aus 1 + 2 provoziert nicht definiertes Verhalten, wie auch die Kombination aus 1 + 3. Solange Sie das Objekt zugreifen nicht tatsächlich durch den Zeiger beschränken, keiner der Definition von „Kicks“ beschränken. Wenn Sie Sie wollte ein Teil entfernen konnte, behalten den ungenutzten beschränken Zeiger und dann 2 und 3 würde in Ordnung sein.

Andere Tipps

Ja "Teil 3" ist nicht definiertes Verhalten. Aus der C99-Spezifikation (6.7.3, Absatz 7):

  

Ein Objekt, das durch eine zugegriffen   beschränken-qualifizierter ed Zeiger hat eine   spezielle Verbindung mit diesem Zeiger.   Dieser Verein, de fi niert in 6.7.3.1   unten erfordert, dass alle Zugriffe auf   dass Objekt Verwendung, die direkt oder   indirekt, dass der Wert von   insbesondere Zeiger.

Ich würde sagen, # 2 schlecht ist. Zum Beispiel könnte der Compiler optimiert, indem sie den Wert an * fooPtr in ein Register geladen wird, und dann die zurück Registerwert wieder schreiben, um foo später - nach dem ++ foo, so dass die ++ foo verloren.

Unter der Annahme, dass alle Teile Ihrer Frage im selben Block auftreten, ist es nicht OK, um den Wert von foo direkt zuzugreifen (Teil 2) noch den Zugriff auf sie über einen anderen Zeiger (Teil 3):

  • 6.7.3.1 formale Definition beschränkt
  

Jeder anderer L-Wert verwendet, um den Wert von X zugreifen soll seine auch hat Adresse basierend auf P.

Die formale Definition von restrict ziemlich schwierig ist, zu folgen (zumindest ist es für mich), aber die folgende weniger formale Beschreibung auch von den Standard-Summen es ziemlich gut (zumindest für diesen Fall):

  

Ein Objekt, das durch einen Filterung der qualifizierten Zeiger zugegriffen wird, hat eine besondere Assoziation   mit diesem Zeiger. Dieser Verein, unten in 6.7.3.1 definiert ist, setzt voraus, dass alle Zugriffe auf das Objekt verwenden, die direkt oder indirekt den Wert des jeweiligen Zeigers.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top