Modo corretto per interpretare questa operazione di dereferenziazione?

0

Ho visto questo esempio in un libro di testo e sono un po 'confuso su come interpretare le regole di precedenza degli operatori. Data questa struttura:

   typedef struct {
   char *data;
   size_t start, end;
   } str_wends;

Lascia che B sia dichiarato come puntatore a questa struttura, ovvero.

   str_wends *B = malloc(sizeof(str_wends));

e si assume B->start != 0 ,

allora questo dovrebbe essere un costrutto legale:

   &B->data[B->start]

che restituirà un riferimento all'offset di stringa di B->start . La domanda è come interpretare le regole di precedenza. Poiché sappiamo che -> e [] hanno la stessa precedenza e si legano da sinistra a destra, perché B->Start è stato valutato prima di B->data[] .

    
posta James S. 06.08.2015 - 01:22
fonte

3 risposte

0

Riguardo a questo:

&B->data[B->start]

affermi nei commenti che:

If I read the tokens from left to right, the operators are ->, [], ->

Ma questi sono non gli operatori che leggono da sinistra a destra: stai includendo ] di chiusura con [ di apertura, anche se -> viene tra loro. Non ha alcun senso. Quando vedi [expression] , l'espressione interna non ha affatto la precedenza rispetto a [] - è un argomento ad esso.

Il codice tokenizza come:

& B -> data [ B -> start ]

e la regola di grammatica per [] è approssimativamente:

lvalue [ rvalue ]

Questo deve ridurre a lvalue:(B->data) [ rvalue:(B->start) ] . Non può ridurre a qualcosa come B -> (data [ B) -> (start ]) , semplicemente non è ben formato. Questo è un problema di grammatica, non di precedenza.

    
risposta data 06.08.2015 - 18:26
fonte
1

In realtà, non importa se B- > start o B- > i dati sono "valutati" per primi. Il risultato dell'interesse è l'indirizzo dell'elemento referenziato, che è la somma dell'indirizzo di base e del prodotto dell'indice e la dimensione dell'elemento. I due addendi sono indipendenti, il che significa che l'ordine della loro valutazione è irrilevante.

Il risultato dell'aggiunta è un lvalue. Valutato sul lato destro di un'espressione di assegnazione, genera un FETCH. Valutato sul lato sinistro, genera un STORE.

    
risposta data 06.08.2015 - 01:47
fonte
1

Since we know that -> and [] have the same precedence and bind left to right, why is B->Start evaluated before B->data[].

Questo è un malinteso comune che semplicemente non morirà.

Precedenza e ordine di valutazione non correlati.

Le regole di precedenza ci dicono quale sia la tua frase ; quali token formano operandi a cui operatori. Ci dice che il tuo codice è equivalente a &(B->data[B->start]) , non (&B->data)[B->start] .

L'ordine in cui questi operandi vengono valutati l'uno rispetto all'altro è guidato da regole completamente separate; in questo caso, è ovvio che B->Start deve essere valutato prima del B->data[] circostante.

I professori universitari hanno davvero bisogno di smettere di dire che una precedenza più alta porta a qualcosa che viene "eseguito" "prima di" qualche altra cosa; assolutamente non.

    
risposta data 25.10.2015 - 03:47
fonte

Leggi altre domande sui tag