Quando si utilizza un puntatore limitare in C, è OK per cambiare una variabile utilizzando il suo identificativo iniziale?

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

  •  30-09-2019
  •  | 
  •  

Domanda

Quando si utilizza un puntatore restrict in C, è OK per modificare la variabile utilizzando la sua iniziale Identifier ? Ad esempio:

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)

... ho cambiato il valore di pippo a foo dopo il restrict fooPtr è stato creato.

Parte 1 sembra OK per me. Sono confuso su Parte 2 . E da quello che ho capito su restrict, Parte 3 è male (compilatore lo permette, ma il suo comportamento non è definito, ed è fino al programmatore di non farlo).

È stato utile?

Soluzione

No, parte 2 non è OK.

La parte specifica dello standard è 6.7.3.1/4. Questa sezione è piuttosto denso, e richiede pochi rilegge, ma P è un puntatore limitare, e X è un oggetto che viene usato per accedere, e che viene modificato. Quindi nel tuo esempio P è fooPtr e X è foo. Poi:

  

Ogni altro valore assegnabile utilizzato per accedere al   valore di X deve anche avere il suo indirizzo   sulla base di P.

"sulla base di" è definito nel paragrafo precedente, e per riassumere, il foo lvalue non hanno il suo indirizzo in base al limitare puntatore P. Quindi la regola è rotto quando si accede l'oggetto foo attraverso il proprio nome.

Parte 3 non è OK per lo stesso motivo, il *fooPtr2 lvalue non è basata sulla P sia, ma è anche usato per l'accesso X.

dico "Non OK" - per essere precisi, la combinazione di 1 + 2 provoca un comportamento indefinito, così come la combinazione di 1 + 3. Finché in realtà non accedere l'oggetto attraverso il puntatore limitare, nessuno della definizione di limitare "calci in". Se si voleva si potrebbe rimuovere Parte 1, mantenere il puntatore limitare inutilizzato, e poi 2 e 3 sarebbe OK.

Altri suggerimenti

Sì, "parte 3" è un comportamento indefinito. Dalla C99 spec (6.7.3, comma 7):

  

Un oggetto a cui si accede attraverso un   limitare-quali puntatore fi cato ha un   associazione speciale con tale puntatore.   Questa associazione, definita in 6.7.3.1   sotto, richiede che tutti gli accessi   tale uso oggetto, direttamente o   indirettamente, il valore di tale   particolare puntatore.

Direi 2 # è male. Per esempio, il compilatore potrebbe ottimizzare il caricamento del valore a * fooPtr in un registro, e poi scrivere che valore del registro di nuovo fuori a foo più tardi - dopo la vostra ++ foo, in modo che l'++ foo è perduto.

Supponendo che tutte le parti della sua domanda si verificano nello stesso blocco, non è OK per accedere al valore di foo direttamente (parte 2), né per l'accesso tramite un altro puntatore (parte 3):

  • 6.7.3.1 formale definizione di limitare
  

Ogni altro valore assegnabile utilizzato per accedere al valore di X è anche il suo indirizzo sulla base di P.

La definizione formale di restrict è abbastanza difficile da seguire (almeno lo è per me), ma la seguente descrizione meno formale anche dalle somme standard, è abbastanza bene (almeno per questo caso):

  

Un oggetto a cui si accede tramite un puntatore limitare qualificato ha un'associazione speciale   con tale puntatore. Questa associazione, definito in 6.7.3.1 seguito, richiede che tutti gli accessi a tale uso oggetto, direttamente o indirettamente, il valore di quel particolare puntatore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top