Visualizzazione dei risultati da 1 a 4 su 4

Discussione: l-value ed r-value

  1. #1

    l-value ed r-value

    Ciao, sto studiando scope dinamico e statico per esame di linguaggi. Sto cercando di capie alcuni esercizi ma non ne vengo fuori:
    qui per esempio mi si chiede di dire qual'è output del programma C-like e l'evoluzione delle variabili.


    codice:
    int v[3]={data di nascita}, i=−3, j=4;
    int f(ref int i, name int z) {
     for (int j = z to z+i) 
       write(v[j] += (i += j));
     return i ++;
    } 
      write(f(j−−,++i + j−−) + i++);
      write(v[i−−], i, j);
    Cè qualcuno che mi può dare una mano a capire?
    Grazie in anticipo

  2. #2
    "name" cosa dovrebbe rappresentare? E cosa c'entrano qui lvalues e rvalues?
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Il testo dell'esercizio dice che bisogna calcolare l-value dopo r-value, espressioni da sinistra a destra, argomenti chiamate da sinistra a destra e indici vettori inizianti da 0

  4. #4
    Non hai risposto alla prima domanda, comunque è sostanzialmente indifferente visto che z non viene modificata dentro alla funzione; inoltre non mi è chiaro cosa intenda per "calcolare prima gli lvalue" - normalmente il fatto che si tratti di l o r value non ha alcuna dipendenza sull'ordine di valutazione, ma solo su cosa ci si può fare (=ad un rvalue non puoi assegnare niente, ad un lvalue sì). Quanto alle chiamate a funzione, tra un argomento e l'altro si assume che ci sia un "sequence point"?

    Comunque, assumendo un linguaggio stile C++ ma con ordine di valutazione degli argomenti fissato e sequence point dopo ogni espressione con side-effects (tutte cose che il C e il C++ non garantiscono), l'idea dovrebbe essere di questo tipo:

    > int v[3]={data di nascita}, i=−3, j=4;
    v={8, 9, 1990}; i=-3; j=4
    > write(f(j−−,++i + j−−) + i++);
    Valutiamo l'espressione f(j--, ++i + j--) + i++; procedendo da sinistra a destra, per prima cosa incontriamo f(j--,++i + j--); supponendo che ci sia un sequence point prima della chiamata a funzione, avremo:
    j-- => j=3
    ++i => i=-2
    j-- => j=2 (ma l'espressione vale 3, visto che è decremento postfisso)
    per cui, il primo argomento (l'"i interno a f") è genericamente j (viene passato per riferimento, per cui quando si entra nella funzione conta il valore che ha in quel momento), mentre z avrà valore -2+3=1

    Dato che f usa variabili locali con nomi uguali a quelli di variabili esterne, per le variabili di f uso il prefisso "f_".
    codice:
    int f(ref int f_i, int f_z) {
     for (int f_j = f_z to f_z+f_i) 
       write(v[f_j] += (f_i += f_j));
     return f_i++;
    }
    Entriamo in f(f_i=j, f_z=1); il ciclo procede da f_j=1 a f_j=1+j=1+2=3. Trattandosi di un linguaggio C-like, gli array hanno indice che parte da 0, quindi suppongo che la clausola "to" di questo ipotetico ciclo for escluda l'estremo superiore specificato.
    Suppongo inoltre che l'estremo superiore venga valutato solo una volta all'inizio (anche perché, per quello che accade internamente al ciclo, in caso contrario il for andrebbe avanti in eterno).

    Per capire la write interna al ciclo, conviene "smontarla":
    codice:
    write(v[j]+=(i+=j));
    diventa (considerando anche che f_i in realtà è j)
    codice:
    j+=f_j;
    v[f_j]+=j;
    write(v[f_j]);
    A questo punto, possiamo "eseguire" le due iterazioni del for:
    codice:
    f_j=1
    j+=1 => j=3
    v[1]+=3 => v[1]=12
    write(v[1]) => stampa '12'
    
    f_j=2
    j+=2 => j=5
    v[2]+=5 =>1995
    write(v[2]) => stampa '1995'
    Quindi si ha il return f_i++, ovvero return j++; viene restituito il valore 5 e j diventa 6.

    Torniamo all'espressione più esterna che stavamo valutando:
    write(f(j−−,++i + j−−) + i++);
    abbiamo determinato che la chiamata a f restituisce 5, e alla sua uscita lo stato delle variabili è
    v={08, 10, 1995}; i=-2; j=6
    quindi si ha
    write(5 + i++);
    ovvero
    write(5+-2);
    e i diventa -1.

    write(v[i−−], i, j);
    E qui incoccio il problema. i-- fa diventare i=-2 e restituisce -1, per cui abbiamo -1 come indice di un array, e questo dovrebbe dare un errore (a meno che non ci sia la convenzione, come in Python, che indici negativi sugli array contano gli elementi dal fondo). Tuttavia, non riesco a capire in che altra maniera si potrebbe arrivare ad avere i positivo - i parte come -3, e in tutto fuori da f ci sono due incrementi di i. L'unica maniera per cui si potrebbe avere una i con valore diverso è se riferendosi a i dentro a f ci si riferisse alla i esterna, ma in tal caso non è chiaro come verrebbe usato il parametro i.
    Per caso l'esercizio specifica meglio le regole di scoping da usare?
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.