Visualizzazione risultati 1 fino 23 di 23

Discussione: a += a++

  1. #1
    L'avatar di binarysun
    binarysun non è connesso Utente storico
    Data registrazione
    02-07-2004
    Messaggi
    2,017

    Predefinito a += a++

    Stavo leggendo un interessante post su come viene risolto il comando
    Codice:
    a = 3
    a += a++
    in C#.

    Incuriosito ho provato anche su PHP scoprendo un comportamento differente ..ed in un caso preoccupante.
    Quanto fa?
    Codice:
    $a += $a++
    Ed ora provate...
    Codice:
    $a += ++$a
    (con $a = 3 o altro numero)

    Ma soprattuto perchè?
    Il motivo è da ricercare nel compilatore ... stasera finisco il post con la soluzione.



    ...forse,
    "L'intelligenza è una pianta che va curata continuamente.
    Dovreste vedere com'è bello, il mio bonsai."
    Rat-man®

    [Gradient Text]
    [Su che server sei?]
    ->flickr

  2. #2
    Guest

    Predefinito

    A me viene 7 come primo risultato e 8 come secondo.
    Non mi pare tanto strano...


    ciao!

  3. #3
    L'avatar di binarysun
    binarysun non è connesso Utente storico
    Data registrazione
    02-07-2004
    Messaggi
    2,017

    Predefinito

    Il secondo dovrebbe dare 7
    "L'intelligenza è una pianta che va curata continuamente.
    Dovreste vedere com'è bello, il mio bonsai."
    Rat-man®

    [Gradient Text]
    [Su che server sei?]
    ->flickr

  4. #4
    Guest

    Predefinito

    Perchè?
    Prima aumenta $a di uno, quindi 4
    Poi assegna ad $a il doppio del suo valore attuale, cioè 4

    = 8


    Ciao!

  5. #5
    L'avatar di binarysun
    binarysun non è connesso Utente storico
    Data registrazione
    02-07-2004
    Messaggi
    2,017

    Predefinito

    Il problema è che
    a += ++a
    equivale a
    a = a + ++a
    l'incremento di a dovrebbe avvenire solo alla fine.
    a = 3 + 4

    altrimenti ++davanti non ha senso
    cioè
    a = 3
    ++a + a = 8 (4 + 4)
    a + ++a = 7 (3 + 4)
    "L'intelligenza è una pianta che va curata continuamente.
    Dovreste vedere com'è bello, il mio bonsai."
    Rat-man®

    [Gradient Text]
    [Su che server sei?]
    ->flickr

  6. #6
    Guest

    Predefinito

    Eh no, come dici tu non avrebbe senso lo spostamento dei ++
    Ci dev'essere la differenza, no?
    E' una questione di precedenze.


    Ciao!

  7. #7
    L'avatar di binarysun
    binarysun non è connesso Utente storico
    Data registrazione
    02-07-2004
    Messaggi
    2,017

    Predefinito

    appunto.

    se a = 3 ad esempio
    a + ++a + a = 3 + 4 + 4
    mentre
    a + a++ + a = 3 + 4 + 3

    Dipende dall'ordine, ma php non sembra prende in considerazione l'ordine.
    "L'intelligenza è una pianta che va curata continuamente.
    Dovreste vedere com'è bello, il mio bonsai."
    Rat-man®

    [Gradient Text]
    [Su che server sei?]
    ->flickr

  8. #8
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,306

    Predefinito

    Premetto che non conosco i dettagli de c#, ma in php l'operatore ++ ha una precedenza più alta di += e compagnia.

    Le espressioni vengono quindi lette come:

    $a += $a++ = ( + ( $a, postfix-increment($a) ) )
    $a += ++$a = ( + ( $a, prefix-increment($a) ) )

    e poi valutate a partire dai nodi più interni (le foglie dell'albero di parsing)

    prendi il valore di $a, poi incrementalo, somma il valore iniziale ad $a, assegna il valore ad $a = 3 + (3+1) = 7
    incrementa $a e prendine il valore, sommalo ad $a, assegna il valore ad $a = 3+1 + 4 = 8


    Il secondo può dare 7 solo se cambi la definizione del linguaggio, o se usi un linguaggio con una diversa definizione. La differenza in questo caso la fa la lazy evaluation: quando vedi una variabile in una espressione, la traduci subito nel suo valore, oppure aspetti fino all'ultimo, quindi ti serve proprio il valore?

    Il c#, a quando capisco da quello che dici, non usa la lazy evaluation, oppure valuta l'albero delle espressioni dalla radice, "richiedendo" ai diversi rami di fornire un risultato.


    edit:
    se a = 3 ad esempio
    a + ++a + a = 3 + 4 + 4
    mentre
    a + a++ + a = 3 + 4 + 3
    no, questo è sbagliato.

    a + ++a + a = 3 + 4 + 4
    ma
    a + a++ + a = 3 + 3 + 4

    l'incremento avviene subito dopo aver preso il valore di a, non dopo aver valutato l'intera espressione
    Ultima modifica di dreadnaut : 30-09-2009 alle ore 13.56.52

  9. #9
    L'avatar di binarysun
    binarysun non è connesso Utente storico
    Data registrazione
    02-07-2004
    Messaggi
    2,017

    Predefinito

    Si è vero, ho fatto vari test, si comporta come c++ in modo invertito.

    Ossia.
    con x = 1

    c#
    x+= x++ + ++x;
    restituisce 5 e procede la trasforma in questo modo
    x = x + x++ + ++x
    x = 1 + 1(+1) + 2+1
    x = 1 + 1 + 3

    c++ e php
    x += x++ + 2
    x += 2(+1) + 2
    x = x + 2(+1) + 2 -> x = (2+1)
    x = 3 + 2 + 2
    x = 7

    Dovrebbe essere questo il comportamento
    CHIARAMENTE preferisco il comportamento del compilatore di C#.
    Sarebbe interessante provare la stessa cosa su MONO per vedere cosa restituisce.
    Ultima modifica di binarysun : 30-09-2009 alle ore 16.07.36
    "L'intelligenza è una pianta che va curata continuamente.
    Dovreste vedere com'è bello, il mio bonsai."
    Rat-man®

    [Gradient Text]
    [Su che server sei?]
    ->flickr

  10. #10
    L'avatar di dementialsite
    dementialsite non è connesso Super Moderatore
    Data registrazione
    19-10-2004
    Residenza
    fuori Padova
    Messaggi
    5,046

    Predefinito

    Nel linguaggio C l'ho sempre vista così:
    - se il simbolo ++ si trova dopo una variabile, questa variabile viene incrementata dopo l'esecuzione dell'istruzione che la contiene
    - se il simbolo ++ si trova prima della variabile, questa variabile viene incrementata prima dell'esecuzione dell'istruzione che la contiene

    Da ciò consegue che:
    - a = 3; a += a++ => a = 7 (prima aggiungo a = 3 ad a = 3, ottenendo a = 6, poi incremento di 1, quindi a = 7)
    - a = 3; a += ++a => a = 8 (prima incremento di 1, cioè a = 4, poi aggiungo a = 4, ottenendo a = 8)

    Statemi bene...
    Le questioni tecniche hanno risposte migliori nel forum pubblico, non trovi?

    When you don't know your next step... improvise

    ALTERVISTA WANTS YOU!
    Vuoi diventare moderatore su AlterVista? Scopri come...

  11. #11
    L'avatar di binarysun
    binarysun non è connesso Utente storico
    Data registrazione
    02-07-2004
    Messaggi
    2,017

    Predefinito

    La differenza tra ++ prima o dopo la so, non mi era chiaro perchè eseguisse prima la ++ e non la += ma come scritto sopra da dreadnaut ha la precedenza al contrario di c#.
    E cmq mi chiedo perchè ++ abbia priorità.

    Ma come scritto nel post che ha fatto nascere il tutto
    http://blogs.msdn.com/lucabol/archiv...31/223580.aspx
    Does it matter which of the previous options is the correct one? Not really because…
    YOU ARE NOT GOING TO WRITE THAT CODE J
    "L'intelligenza è una pianta che va curata continuamente.
    Dovreste vedere com'è bello, il mio bonsai."
    Rat-man®

    [Gradient Text]
    [Su che server sei?]
    ->flickr

  12. #12
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,306

    Predefinito

    Gli operatori ++ e += hanno la stessa relazione di precedenza anche in C#, quindi la differenza dev'essere un'altra.

    E quello che ha scritto sopra dementialsite è incorretto: non si tratta di esecuzione prima o dopo dell'istruzione, ma prima o dopo la valutazione della variabile. La differenza è quella fra "prendo il valore, poi come side-effect aumento la variabile" e "incremento la variabile, e poi ne prendo il valore", ma questo viene fatto durante l'istruzione (da non confondersi con l'espressione.

  13. #13
    L'avatar di binarysun
    binarysun non è connesso Utente storico
    Data registrazione
    02-07-2004
    Messaggi
    2,017

    Predefinito

    Leggi il link del mio post precedente
    and knowing that c# evaluates expressions left to right
    ...è Lead Program Manager alla microsoft, penso sappia ciò che dice.

    ++a e a++
    se faccio un echo dovrei avere valori differenti dato che
    viene restituito il valore incrementato nel primo caso
    nel secondo viene restituita la variabile e poi incrementata.

    Ho letto adesso quello che aveva scrito, si la descrizione non è corretta, non è una "sostituzione".
    Ultima modifica di binarysun : 30-09-2009 alle ore 16.49.06
    "L'intelligenza è una pianta che va curata continuamente.
    Dovreste vedere com'è bello, il mio bonsai."
    Rat-man®

    [Gradient Text]
    [Su che server sei?]
    ->flickr

  14. #14
    Guest

    Predefinito

    Citazione Originalmente inviato da binarysun Visualizza messaggio
    Leggi il link del mio post precedente
    ++a e a++
    se faccio un echo dovrei avere valori differenti dato che
    viene restituito il valore incrementato nel primo caso
    nel secondo viene restituita la variabile e poi incrementata.
    E infatti è così.


    ciao!

  15. #15
    L'avatar di binarysun
    binarysun non è connesso Utente storico
    Data registrazione
    02-07-2004
    Messaggi
    2,017

    Predefinito

    LA seconda parte era la risposta per la #10, ma poi ho subito rileto quello scritto ed ho modificato il post.

    La prima parte era riferita a
    Gli operatori ++ e += hanno la stessa relazione di precedenza anche in C#, quindi la differenza dev'essere un'altra.
    Ultima modifica di binarysun : 30-09-2009 alle ore 16.58.07
    "L'intelligenza è una pianta che va curata continuamente.
    Dovreste vedere com'è bello, il mio bonsai."
    Rat-man®

    [Gradient Text]
    [Su che server sei?]
    ->flickr

  16. #16
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,306

    Predefinito

    Citazione Originalmente inviato da binarysun Visualizza messaggio
    Leggi il link del mio post precedente
    and knowing that c# evaluates expressions left to right
    ...è Lead Program Manager alla microsoft, penso sappia ciò che dice.
    Sarebbe bello. Afferma anche che "By the way, in c++ the behavior for this expression is undefined…" quando in realtà lo è. Ma saranno questioni di interpretazione.

    edit: geniale però il modo in cui ti butta li tre risposte alla fine, e non ti dice quale sia vera - qualcuno potrebbe usare un codice simile a quello, e voler sapere perché le cose funzionano diversamente, se è stato un errore o no.

    Comunque anche php e c/c++ sono left associative, quindi la differenza non è quella.
    Ultima modifica di dreadnaut : 30-09-2009 alle ore 17.08.25

  17. #17
    L'avatar di binarysun
    binarysun non è connesso Utente storico
    Data registrazione
    02-07-2004
    Messaggi
    2,017

    Predefinito

    Sono tutte vere, sono tre esempi ed è il risultato che da c#, semplciemente alla fine dice "qual'è il comportamento correto? non è importante dato che è codice da non usare"

    Ma quindi se mi dici che anche c++ è left associative ...come azzo funziona?
    un dato di fatto (ho provato) è che con
    x=1;
    x+= x++ + ++x;
    c# restituisce 5
    c++ restituisce 7

    Dando per scontato che i sistema di Pre-increment e post-increment funzioni in modo identico l'unica differenza è l'ordine.

    in c# la funzione sopra scritta:
    x = x+ x++ + ++x; .. = 5
    x = x++ + ++x + x; ... = 7

    in c++
    x = x+ x++ + ++x; .. = 7
    x = x++ + ++x + x; ... = 7

    per c++ ho usato visual studio c++
    "L'intelligenza è una pianta che va curata continuamente.
    Dovreste vedere com'è bello, il mio bonsai."
    Rat-man®

    [Gradient Text]
    [Su che server sei?]
    ->flickr

  18. #18
    L'avatar di AlexKidd
    AlexKidd non è connesso Altervistiano Junior
    Data registrazione
    09-02-2007
    Messaggi
    516

    Predefinito

    effettivamente c'è qualcosa di strano, ma il problema risiede solamente nell'operatore +=

    analizzate questo:

    x=1;
    x+= (x=10);

    In C++ alla fine x==20
    in C# (mono) alla fine x==11

    in C# se il valore X durante la valutazione dell'espressione cambia, non viene aggiornato per l'operazione di assegnamento composto

    non saprei stabilire quale dei due sia più corretto, certamente il comportamento in C++ deriva da linguaggi che ormai hanno fatto la storia e una larga maggioranza di programmatori dovrebbe aspettarsi questo in qualsiasi linguaggio

    È strano però che tale differenza non l'abbia mai letta su nessun testo che spiega C# confrontandolo con C++ e Java

    Edit: In Java alla fine x==11

    Quindi sembrerebbe che i linguaggi, compilati, che girano in una VM si comportino diversamente
    Ultima modifica di AlexKidd : 30-09-2009 alle ore 18.34.33

  19. #19
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,306

    Predefinito

    e x = x + (x = 10); cosa ti restuisce? In teoria (e spero anche in pratica) dovrebbe essere lo stesso.

    Mi piacerebbe trovare una spiegazione completa di questa cosa - gli esempi purtroppo sono compatibili con più di una spiegazione, fra cui un diverso ordine di visita dell'albero e late/early binding, ma non si capisce
    Ultima modifica di dreadnaut : 30-09-2009 alle ore 18.33.34

  20. #20
    L'avatar di AlexKidd
    AlexKidd non è connesso Altervistiano Junior
    Data registrazione
    09-02-2007
    Messaggi
    516

    Predefinito

    Trovato! http://en.wikipedia.org/wiki/Augmented_assignment

    È un problema di ottimizzazione, che consiste nel non aggiornare la variabile

    Ecco perchè il comportamento in C#/Java mi sapeva tanto di assembler....

    Comunque questa cosa crea non poca confusione e potrebbe esser la madre di un sacco di bug

  21. #21
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,306

    Predefinito

    uhm, non c'è però ancora una spiegazione delle differenze, o sbaglio?

    Ho provato in c++ comunque, e le espressioni x += ... danno lo stesso risultato di quelle x = x + ...

  22. #22
    L'avatar di AlexKidd
    AlexKidd non è connesso Altervistiano Junior
    Data registrazione
    09-02-2007
    Messaggi
    516

    Predefinito

    già.... su wikipedia ci si limita a una descrizione formale dell'operazione, che però è la base da cui partire per ragionare su questo comportamento.

    Sul K&R l'assegnamento composto viene descritto nello stesso modo in cui viene enunciato in C# e imagino che nulla cambi anche per altri linguaggi

    Secondo me una possibile causa è da ricercare nel modo in cui sono viste le variabili nei linguaggi Java e C# che, come ben sappiamo, sono considerati oggetti e non tipi primitivi

  23. #23
    L'avatar di binarysun
    binarysun non è connesso Utente storico
    Data registrazione
    02-07-2004
    Messaggi
    2,017

    Predefinito

    Citazione Originalmente inviato da AlexKidd Visualizza messaggio
    Secondo me una possibile causa è da ricercare nel modo in cui sono viste le variabili nei linguaggi Java e C# che, come ben sappiamo, sono considerati oggetti e non tipi primitivi
    Lo penso anche io, l'operatore ++ fa parte della struttura/classe integer.
    "L'intelligenza è una pianta che va curata continuamente.
    Dovreste vedere com'è bello, il mio bonsai."
    Rat-man®

    [Gradient Text]
    [Su che server sei?]
    ->flickr

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •