PDA

View Full Version : [C] risultato di: a=a++;


gege_63
09-03-2010, 23:26
il quesito è il seguente:
cosa viene stampato come valore di a dal seguente frammento di sw:

a=0;
a=a++;
printf(a);

ora:
lo so che a=a++; non ha senso pratico, ma qualcuno sa spiegarmi perchè il valore finale di a è 0 e non 1?
O meglio: è vero che l'incremento avviene dopo l'assegnazione, però riguarda sempre la variabile a.
Riassumendo: ero convinto che a alla fine valesse 1 ed invece vale 0.
grazie a che vorrà aiutarmi con questo problema esclusivamente teorico e poco pratico.

Agat
09-03-2010, 23:51
Ma a e' int ?

Supposto sia int, fa proprio 1


int a=0;
a=a++;
printf("a=%d\n", a);


Edit: Dimenticavo che il perche', e' la precedenza inferiore dell'assegnamento rispetto all'incremento :D

Black imp
10-03-2010, 00:02
il quesito è il seguente:
cosa viene stampato come valore di a dal seguente frammento di sw:

a=0;
a=a++;
printf(a);

ora:
lo so che a=a++; non ha senso pratico, ma qualcuno sa spiegarmi perchè il valore finale di a è 0 e non 1?
O meglio: è vero che l'incremento avviene dopo l'assegnazione, però riguarda sempre la variabile a.
Riassumendo: ero convinto che a alla fine valesse 1 ed invece vale 0.
grazie a che vorrà aiutarmi con questo problema esclusivamente teorico e poco pratico.

scusa tu stai compilando con qualche livello di ottimizzazione?

l'ho appena compilato e mi dà 1.

Galdor
10-03-2010, 10:16
In effetti dovrebbe stampare 1 anche secondo me...

flx2000
10-03-2010, 10:23
a=0 !!!!

1. Il buffer si predispone per fare a = a ponendo la seconda a nello stack
2. Il buffer incrementa a di 1 la a nello stack
3. Il buffer esegue a = a considerando la a PRIMA dell'incremento perché è a++ e non ++a
4. Lo stack viene eluso dalla precedenza
5. Il buffer esce con a = 0

agente mm8
10-03-2010, 12:47
Provato e stampa 1... come mi sembra anche logico, del resto.

flx2000
10-03-2010, 13:34
quindi secondo te l'incremento quando viene fatto? :mbe: mica l'ho capita la spiegazione che hai dato... e soprattutto, l'hanno compilato e stampa 1 (non ho tempo di provarlo personalmente ora...)

E' un tipico caso di programmazione che dipende dal compilatore.

L'ho verificato io stesso pochi istanti fa con VS C++ e C# e dà 0.
Dovrei provare con g++ per vedere se dà 1.

Di fatto, la "logica" naturale (del gcc ad esempio) vuole che si legga in questo modo: "Viene eseguita l'operazione a destra e alla fine assegnata alla parte sinistra".
Allora è chiaro che le fasi sarebbero:
1. Eseguo l'incremento (a passa da 0 a 1)
2. Lo assegno a se stesso (a resta a, cioè 1)

Diversi compilatori possono generare diversi risultati se si trovano a lavorare su funzioni di questo tipo perché dipende tutto da come usano lo stack, che non a caso è una delle cose che differenzia maggiormente tra loro i compilatori.

||ElChE||88
10-03-2010, 13:58
a viene usato sia come come lvalue che rvalue nell'ambito dello stesso sequence-point, quindi (secondo lo standard C++) il risultato di quell'espressione non è definito.

gege_63
10-03-2010, 20:36
non mi aspettavo risposte così numerose al mio quesito: grazie.
il mio risultato , cioè 0, lo ottengo sia con DEVC++ che con visual C#.

vorrei sapere, da chi ottiene 1, con che compilatore lavora.
grazie ancora a tutti.

gege_63
10-03-2010, 21:07
Di fatto, la "logica" naturale (del gcc ad esempio) vuole che si legga in questo modo: "Viene eseguita l'operazione a destra e alla fine assegnata alla parte sinistra".
Allora è chiaro che le fasi sarebbero:
1. Eseguo l'incremento (a passa da 0 a 1)
2. Lo assegno a se stesso (a resta a, cioè 1)



non sono tanto daccordo, perchè è un postincremento:
se il codice fosse

a=0;
b=a++;
printf(b);

il risultato sarebbe sicuramente b=0, perchè l'incremento avviene dopo l'assegnazione.

flx2000
11-03-2010, 08:51
non sono tanto daccordo, perchè è un postincremento:
se il codice fosse

a=0;
b=a++;
printf(b);

il risultato sarebbe sicuramente b=0, perchè l'incremento avviene dopo l'assegnazione.

Se guardi bene anch'io ho dato risposta 0. La spiegazione che citi è un'ipotesi che ho cercato di dare per giustificare i casi in cui è uscito 1 (dando per scontato che qualcuno abbia effettivamente ottenuto 1)

AnonimoVeneziano
11-03-2010, 09:06
Al di là del fatto dell'implementazione specifica del compilatore, secondo me il risultato più giusto (e che uno si aspetta da questa operazione) è zero.

La ragione è che una espressione come "a++" viene valutata prima dell'incremento, quindi il valore in cui una espressione come "a++" , se il valore di a prima dell'espressione è 0, è proprio 0.

Ricapitolando quindi :

a=0; viene assegnato ad a il valore 0
a=a++; prima viene valutato "a++" e quindi 0, poi viene effettuato l'incremento, quindi a = 1 , poi però viene effettuato l'assegnamento con il valore 0 memorizzato in precedenza dalla valutazione di a++ e quindi a torna ad essere 0.

Ciao

Galdor
11-03-2010, 09:11
il mio risultato , cioè 0, lo ottengo sia con DEVC++ che con visual C#.
vorrei sapere, da chi ottiene 1, con che compilatore lavora.
grazie ancora a tutti.

Con Visual C++ 2008 express edition a me stampa 1 che credo sia il risultato più logico...
Pensando a come funzioni lo stack e il compilatore probabilmente è giusto che esca 0, ma per logica dovrei ottenere 1, se metto quel ++ vorrà pur dire che voglio incrementare a no? se lo faccio prima o dopo il risultato non dovrebbe comunque cambiare; mi sembra più un "difetto" del compilatore

kralizec
11-03-2010, 09:33
Al di là del fatto dell'implementazione specifica del compilatore, secondo me il risultato più giusto (e che uno si aspetta da questa operazione) è zero.

La ragione è che una espressione come "a++" viene valutata prima dell'incremento, quindi il valore in cui una espressione come "a++" , se il valore di ha prima dell'espressione è 0, è proprio 0.

Ricapitolando quindi :

a=0; viene assegnato ad a il valore 0
a=a++; prima viene valutato "a++" e quindi 0, poi viene effettuato l'incremento, quindi a = 1 , poi però viene effettuato l'assegnamento con il valore 0 memorizzato in precedenza dalla valutazione di a++ e quindi a torna ad essere 0.

Ciao

Allora, a++ è un POST incremento, significa che, al contrario di ++a, l'incremento della variabile avviene DOPO l'assegnamento, quindi il programma dovrebbe procedere come segue:

#include <stdio.h>

int main(){
int a; // Inizializzazione

a=0; // assegnazione di 0 ad "a"

a=a++;
/* Questa dovrebbe tradursi così:
a=a; Assegnazione di 0 ad a, di nuovo
a++; incremento di a, quindi dopo l'istruzione: a = 1;
*/
printf("a=%i\n", a); // Stampa
}


Questa interpretazione, secondo me, spiega correttamente il fatto che il risultato sia 1, provato su macOS, con gcc 4.4.0 20080801 (experimental) e su macchina virtuale con ubuntu, con gcc 4.4.1 (Ubuntu 4.4.1-4ubuntu9).

Non so come possa venire 0 a qualcuno, a meno di errori di trascrizione del codice, vorrebbe dire che il compilatore usato ha dei problemi rispetto allo standard nella gestione degli operatori come ++

flx2000
11-03-2010, 09:45
Allora, a++ è un POST incremento, significa che, al contrario di ++a, l'incremento della variabile avviene DOPO l'assegnamento, quindi il programma dovrebbe procedere come segue:

#include <stdio.h>

int main(){
int a; // Inizializzazione

a=0; // assegnazione di 0 ad "a"

a=a++;
/* Questa dovrebbe tradursi così:
a=a; Assegnazione di 0 ad a, di nuovo
a++; incremento di a, quindi dopo l'istruzione: a = 1;
*/
printf("a=%i\n", a); // Stampa
}


Questa interpretazione, secondo me, spiega correttamente il fatto che il risultato sia 1, provato su macOS, con gcc 4.4.0 20080801 (experimental) e su macchina virtuale con ubuntu, con gcc 4.4.1 (Ubuntu 4.4.1-4ubuntu9).

Non so come possa venire 0 a qualcuno, a meno di errori di trascrizione del codice, vorrebbe dire che il compilatore usato ha dei problemi rispetto allo standard nella gestione degli operatori come ++

Appena riprovato.
Visual Studio 2008, C#:

{
int a = 0;
a = a++;
}

Il breakpoint sulla parentesi conclusiva segna chiaramente a = 0 in fase di esecuzione del codice.

||ElChE||88
11-03-2010, 09:53
mi sembra più un "difetto" del compilatore
vorrebbe dire che il compilatore usato ha dei problemi rispetto allo standard nella gestione degli operatori come ++
E dire che l'ho già scritto sopra...
Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual
expressions, and the order in which side effects take place, is unspecified. Between the previous
and next sequence point a scalar object shall have its stored value modified at most once by the evaluation
of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.
The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full
expression; otherwise the behavior is undefined. [Example:
i = v[i++]; // the behavior is unspecified
i = 7, i++, i++; // i becomes 9
i = ++i + 1; // the behavior is unspecified
i = i + 1; // the value of i is incremented

Galdor
11-03-2010, 10:04
Ho capito che lo standard non definisce un comportamento preciso in questo caso, ma se tu dovessi scrivere un compilatore che esegue quelle istruzioni gli faresti tornare 1 o 0 ?
Chiaro che sia che torni uno o l'altro il compilatore rispetterà lo standard, ma IMHO se torna 1 è meglio

||ElChE||88
11-03-2010, 10:07
Ho capito che lo standard non definisce un comportamento preciso in questo caso, ma se tu dovessi scrivere un compilatore che esegue quelle istruzioni gli faresti tornare 1 o 0 ?
Chiaro che sia che torni uno o l'altro il compilatore rispetterà lo standard, ma IMHO se torna 1 è meglio
Se lo standard dice che non è definito allora il compilatore può restituire quello che gli pare, che ti piaccia o meno.

kralizec
11-03-2010, 10:20
ok, abbiamo capito che non è ben definito il comportamento, ma c'è anche da dire che tu hai quotato è dello standard del c++, non del c :Prrr:

per fix2000, Visual Studio, per quanto riguarda la mia esigua esperienza, si rivela spesso discostante da gcc... per non parlare del fatto che tu hai compilato in C# e non in C :)

io ho solo riportato l'output delle mie compilazioni, che rispecchiano (fortunatamente per me) le mie aspettative :ciapet:

||ElChE||88
11-03-2010, 11:15
ok, abbiamo capito che non è ben definito il comportamento, ma c'è anche da dire che tu hai quotato è dello standard del c++, non del c :Prrr:
Azz, hai ragione, non so perché pensavo si parlasse di C++. :doh:

Comunque non cambia molto :p
Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.

This paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;

kralizec
11-03-2010, 12:29
:doh:

flx2000
11-03-2010, 15:34
[...]
per fix2000, Visual Studio, per quanto riguarda la mia esigua esperienza, si rivela spesso discostante da gcc... per non parlare del fatto che tu hai compilato in C# e non in C :)
[...]

Giusto per precisare, Python, Java, C#, C++ e non so quanti altri linguaggi sono ampliamenti o (ri/e)voluzioni del C, quindi hanno una base in comune e queste operazioni sono prese pare-pare del linguaggio base, cioè dal C nudo.
Allora, visto che in C non è definito un comportamento standard per quel tipo di operazione, ognuno dei compilatori fa come più gli conviene e danno risultati che potrebbero essere validi anche per il C base.

||ElChE||88
11-03-2010, 15:55
Giusto per precisare, Python, Java, C#, C++ e non so quanti altri linguaggi sono ampliamenti o (ri/e)voluzioni del C, quindi hanno una base in comune e queste operazioni sono prese pare-pare del linguaggio base, cioè dal C nudo.
Allora, visto che in C non è definito un comportamento standard per quel tipo di operazione, ognuno dei compilatori fa come più gli conviene e danno risultati che potrebbero essere validi anche per il C base.
Falso.
Java e C# hanno una sintassi C-like (Python nemmeno quella), e la somiglianza finisce li.
Il risultato dell'espressione del primo post è ben definito in entrambi i linguaggi.

WarDuck
11-03-2010, 17:14
Anche se la specifica del linguaggio presenta ambiguità (bella roba aggiungo io :rolleyes: ), il compilatore deve effettuare una scelta ben precisa per eliminare tale ambiguità.

E' bene cmq osservare che linguaggio != compilatore.

AnonimoVeneziano
11-03-2010, 18:44
Allora, a++ è un POST incremento, significa che, al contrario di ++a, l'incremento della variabile avviene DOPO l'assegnamento, quindi il programma dovrebbe procedere come segue:



A dire il vero il post incremento avviene dopo "l'uso", non dopo l'assegnamento.

L'uso può essere inteso come valutazione in una espressione.

Ad esempio se avessimo avuto



a = a++ + 3;



L'uso sarebbe stato "ottenere il valore di a per l'uso all'interno dell'espressione di somma" e non l'assegnamento.

Chiaro che poi dipende da come il compilatore implementa la grammatica che gestisce gli assegnamenti.

marco.r
11-03-2010, 18:48
Anche se la specifica del linguaggio presenta ambiguità (bella roba aggiungo io :rolleyes: ), il compilatore deve effettuare una scelta ben precisa per eliminare tale ambiguità.

L'unica scelta precisa che dovrebbe fare in questi casi un compilatore sarebbe formattare il disco fisso e fermare la ventola del processore per punire il programmatore che si affida ad un comportamento indefinito.

Un comportamento indefinito e' diverso da un comportamento che dipende dal compilatore. Puo' benissimo essere che lo stesso compilatore, stessa versione, restituisca un valore diverso a seconda delle ottimizzazioni che fai, oppure da esecuzione a esecuzione dello stesso binario.

kralizec
11-03-2010, 21:17
A dire il vero il post incremento avviene dopo "l'uso", non dopo l'assegnamento.


mi pareva ovvio che la mia frase fosse contestualizzata... noi avevamo un assegnamento :)

kralizec
11-03-2010, 21:20
L'unica scelta precisa che dovrebbe fare in questi casi un compilatore sarebbe formattare il disco fisso e fermare la ventola del processore per punire il programmatore che si affida ad un comportamento indefinito.

Un comportamento indefinito e' diverso da un comportamento che dipende dal compilatore. Puo' benissimo essere che lo stesso compilatore, stessa versione, restituisca un valore diverso a seconda delle ottimizzazioni che fai, oppure da esecuzione a esecuzione dello stesso binario.

per il fatto che possa cambiare il risultato in base a compilazioni diverse si, ma una volta compilato il risultato dovrebbe essere sempre quello... no?

AnonimoVeneziano
11-03-2010, 21:24
mi pareva ovvio che la mia frase fosse contestualizzata... noi avevamo un assegnamento :)

Se nel compilatore la grammatica che implementa l'assegnamento è di questo tipo


assignment -> identifier = expression


Allora qualsiasi cosa succeda prima viene valutata l'espressione a destra e poi effettuato l'assegnamento.

Al contrario, se l'assegnamento con un solo operando a destra avesse un modo "speciale" di gestione da parte del compilatore diversa dall'assegnamento con a destra una espressione allora avremmo un caso di ambiguità della grammatica del compilatore, perchè "a = a++" potrebbe essere gestito sia attraverso la produzione con l'espressione che la produzione diretta, quindi non credo che nessun compilatore differenzi i due casi .

kralizec
11-03-2010, 21:59
l'ambiguità dovrebbe stare proprio qui... a = a++

viene calcolato il valore che verrà usato per l'assegnamento di valore, in questo caso 0;

a questo punto, se il compilatore fa PRIMA l'assegnamento, e POI il post-incremento, il risultato sarà 1, altrimenti, "a" viene incrementata, ma poi l'assegnamento la riporta a 0, poiché il valore da attribuire alla variabile era già stata assegnata

maulattu
11-03-2010, 22:02
tra le altre cose, le direttive Misra C vietano istruzioni del genere, così da rendere il codice più portabile possibile ed evitare risultati diversi a seconda del compilatore

WarDuck
11-03-2010, 22:54
L'unica scelta precisa che dovrebbe fare in questi casi un compilatore sarebbe formattare il disco fisso e fermare la ventola del processore per punire il programmatore che si affida ad un comportamento indefinito.


No, basterebbe definire l'ordine delle operazioni in quel caso, come dice kralizec.

Se metti a disposizione del programmatore delle istruzioni devono avere un senso, altrimenti le segnali come errore e fine della storia.


Un comportamento indefinito e' diverso da un comportamento che dipende dal compilatore. Puo' benissimo essere che lo stesso compilatore, stessa versione, restituisca un valore diverso a seconda delle ottimizzazioni che fai, oppure da esecuzione a esecuzione dello stesso binario.

Se le specifiche del linguaggio dicono che non è definito, questo non significa che in fase implementativa non venga presa una soluzione al riguardo.

Come ti ho detto quello che si dovrebbe fare tipicamente è forzare l'ordine delle operazioni. O almeno è quello che farei io :D.

Edit: cmq molto banalmente stavo leggendo per Java che l'espressione (a++) ha come valore a, questo giustifica il perché a = a++ non modifica il valore di a

The increment/decrement operators can be applied before (prefix) or after (postfix) the operand. The code result++; and ++result; will both end in result being incremented by one. The only difference is that the prefix version (++result) evaluates to the incremented value, whereas the postfix version (result++) evaluates to the original value. If you are just performing a simple increment/decrement, it doesn't really matter which version you choose. But if you use this operator in part of a larger expression, the one that you choose may make a significant difference.

The following program, PrePostDemo, illustrates the prefix/postfix unary increment operator:



class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
System.out.println(i); // "4"
++i;
System.out.println(i); // "5"
System.out.println(++i); // "6"
System.out.println(i++); // "6"
System.out.println(i); // "7"
}
}

rеpne scasb
12-03-2010, 09:03

flx2000
12-03-2010, 11:29
Falso.
Java e C# hanno una sintassi C-like (Python nemmeno quella), e la somiglianza finisce li.
Il risultato dell'espressione del primo post è ben definito in entrambi i linguaggi.

Chi ha parlato di somiglianza nella forma?
La sintassi è completamente indifferente nella mia considerazione, perché il Python incorpora di fatto le librerie C (ad esempio Math) e non dire che l'espressione è ben definita perché non è vero.
Se l'operatore di incremento a destra o a sinistra non esiste nemmeno, come potrebbe essere definito?
L'esecuzione di Python è delegata ad un parser scritto in C con librerie compilate dal C; l'ambiguità si realizza in fase di compilazione, (altrimenti darebbe un errore di sintassi), quindi sia Python che Java possono essere vittime di ambiguità simili (infatti il Python evita il problema eliminando del tutto il codice ambiguo e non attraverso un parser esente dall'errore di compilazione).

||ElChE||88
12-03-2010, 12:15
Chi ha parlato di somiglianza nella forma?
La sintassi è completamente indifferente nella mia considerazione, perché il Python incorpora di fatto le librerie C (ad esempio Math) e non dire che l'espressione è ben definita perché non è vero.
Se l'operatore di incremento a destra o a sinistra non esiste nemmeno, come potrebbe essere definito?
L'esecuzione di Python è delegata ad un parser scritto in C con librerie compilate dal C; l'ambiguità si realizza in fase di compilazione, (altrimenti darebbe un errore di sintassi), quindi sia Python che Java possono essere vittime di ambiguità simili (infatti il Python evita il problema eliminando del tutto il codice ambiguo e non attraverso un parser esente dall'errore di compilazione).
Python non lo conosco, e infatti ho scritto entrambi riferendomi a C# e Java.
Quello che dici su Java invece è una castroneria; secondo la specifica del linguaggio Java quell'espressione ha un risultato ben definito, e cioe 0.
Il perché lo puoi leggere nell'ultimo post di WarDuck .

DanieleC88
12-03-2010, 12:29
In Python non sono concessi postincrementi e preincrementi.

flx2000
12-03-2010, 12:45
Python non lo conosco, e infatti ho scritto entrambi riferendomi a C# e Java.
Quello che dici su Java invece è una castroneria; secondo la specifica del linguaggio Java quell'espressione ha un risultato ben definito, e cioe 0.
Il perché lo puoi leggere nell'ultimo post di WarDuck .

Ma allora cosa mi citi a fare il Python se poi si scopre che nemmeno lo conosci?
Comunque sapevo benissimo che non lo conoscevi, sennò non mi avresti detto, sbagliando, che quei casi erano definiti...
Dove avrei analizzato la sintassi di Java nel mio post?

In Python non sono concessi postincrementi e preincrementi.

Esatto, glielo avevo già fatto presente.

Chiarendo che sto parlando di linguaggio C (e non di C#,C++,C99,...) "in generale (*)" accade che:


a=0; mov [ebp-4h],0h

a=a++; mov eax,[ebp-4h]
inc [ebp-4h]
mov [ebp-4h],eax



Hai finemente descritto quello che ho detto fin dalle prime risposte a questo topic :)

||ElChE||88
12-03-2010, 14:05
Ma allora cosa mi citi a fare il Python se poi si scopre che nemmeno lo conosci?
Comunque sapevo benissimo che non lo conoscevi, sennò non mi avresti detto, sbagliando, che quei casi erano definiti...
I casi sono 2: o non sai leggere, o hai capito di aver fatto una figura di merda e ti stai arrampicando sugli specchi per "rimediare".
Hai scritto che il Python è una rievoluzione/ampliamento del C... evidentemente il Python lo conosci ancora meno di me:
L'esecuzione di Python è delegata ad un parser scritto in C con librerie compilate dal C;
Dimostri di non saper distinguere tra linguaggio e implementazione.
Newsflash: oltre a CPython esistono anche Jython (Python implementato in Java, ma dai!), IronPython (Python implementato in .NET, che roba!), PyPy (Python implementato in Python, fantascieeenza!).
Dove avrei analizzato la sintassi di Java nel mio post?
La sintassi? E chi ha parlato di sintassi? Io mi riferivo alla seguente castroneria:
quindi sia Python che Java possono essere vittime di ambiguità simili
Che, ripeto, è assolutamente falso.

Kralizek
12-03-2010, 14:20
Allora, a++ è un POST incremento, significa che, al contrario di ++a, l'incremento della variabile avviene DOPO l'assegnamento, quindi il programma dovrebbe procedere come segue:

#include <stdio.h>

int main(){
int a; // Inizializzazione

a=0; // assegnazione di 0 ad "a"

a=a++;
/* Questa dovrebbe tradursi così:
a=a; Assegnazione di 0 ad a, di nuovo
a++; incremento di a, quindi dopo l'istruzione: a = 1;
*/
printf("a=%i\n", a); // Stampa
}


Questa interpretazione, secondo me, spiega correttamente il fatto che il risultato sia 1, provato su macOS, con gcc 4.4.0 20080801 (experimental) e su macchina virtuale con ubuntu, con gcc 4.4.1 (Ubuntu 4.4.1-4ubuntu9).

Non so come possa venire 0 a qualcuno, a meno di errori di trascrizione del codice, vorrebbe dire che il compilatore usato ha dei problemi rispetto allo standard nella gestione degli operatori come ++

io la tradurrei cosí invece:


a++; incremento di a, quindi dopo l'istruzione: a = 1;
a=a; Assegnazione di 0 ad a, di nuovo


l'assegnazione all'LValue viene fatta dopo aver valutato l'espressione RValue :)

ps: bel nick :P

flx2000
12-03-2010, 15:22
@||ElChE||88:
Dai, lascia perdere. Ogni volta ci deve essere qualcuno che cerca di insegnare agli altri la sua limitatissima verità...
Non sei assolutamente riuscito a capire quello di cui parlo, e sta cosa sta diventando veramente noiosa.
Stavo per risponderti a tono ma mi pare di fare la solita guerra coi sapientoni di turno. Sai che c'è? Ti lascio la ragione dei cretini.
Io so quanto conosco Python. Non puoi certo minare alle mie conoscenze con le tue allusioni da troll guerrafondaio.

||ElChE||88
12-03-2010, 15:43
@||ElChE||88:
Dai, lascia perdere. Ogni volta ci deve essere qualcuno che cerca di insegnare agli altri la sua limitatissima verità...
Non sei assolutamente riuscito a capire quello di cui parlo, e sta cosa sta diventando veramente noiosa.
Stavo per risponderti a tono ma mi pare di fare la solita guerra coi sapientoni di turno. Sai che c'è? Ti lascio la ragione dei cretini.
Io so quanto conosco Python. Non puoi certo minare alle mie conoscenze con le tue allusioni da troll guerrafondaio.
Abbi la decenza di risparmiarci le solite scuse e accuse di chi si è reso conto di aver sbagliato e non ha il coraggio di ammetterlo, ricorrendo alla buona vecchia "ragione dei cretini".

Grazie.

bobbytre
12-03-2010, 15:50
http://tli.tl/Fc9F0E

kralizec
12-03-2010, 18:57
io la tradurrei cosí invece:


a++; incremento di a, quindi dopo l'istruzione: a = 1;
a=a; Assegnazione di 0 ad a, di nuovo


l'assegnazione all'LValue viene fatta dopo aver valutato l'espressione RValue :)

ps: bel nick :P

la tua soluzione mi pare più adatta ad un ++a che un a++... :-)


ps
ci ho messo davvero 30 secondi buoni per capire che non sono diventato scemo autoquotandomi, ma eri davvero un'altra persona... bel nick! XD

cionci
12-03-2010, 19:17
||ElChE||88 e fix2000: per favore terminate istantaneamente questo flame.

flx2000
12-03-2010, 19:59
||ElChE||88 e fix2000: per favore terminate istantaneamente questo flame.

Volentieri, da canto mio l'ho già fatto al post precedente. Mi scuso con gli altri.

||ElChE||88
12-03-2010, 20:11
Interessante, non sapevo che "terminare il flame" e "accusare gli altri di essere cretini e troll" fossero equivalenti.
Ogni giorno si impara qualcosa di nuovo! :D

gugoXX
12-03-2010, 22:34
In C# l'esecuzione restituisce 0.
Questo perche' in C# l'operatore di postincremento ++ viene eseguito immediatamente dopo l'utilizzo dell'oggetto, in questo caso un intero.
L'esecuzione quindi risulta

int a=0;
a=a++;


viene salvato temporaneamente il valore 0 di a perche' deve essere utilizzato nella valutazione successiva.
Viene incrementato a (in questo momento vale 1)
il valore precedentemente salvato viene utilizzato per continuare l'operazione.
La prosecuzione prevede un assegnazione. Viene di nuovo assegnato 0 ad a.

Altro esempio:

int a = 2;
int q = 123 + a++ + a++;


1) Viene salvato temporaneamente il valore di a, ovvero 2.
2) a viene incrementato di uno. (che vale 3 quindi)
3) viene eseguita la somma tra 123 e il valore 2 salvato = 125
4) viene salvato temporaneamente il valore di a, ovvero 3.
5) viene incrementato il valore di a, che varra' quindi 4.
6) viene eseguita la somma tra 125 e 3 precedentemente salvato = 128, che viene assegnata a q

I passi 2 e 3 possono essere scambiati tra di loro nell'esecuzione
Cosi' anche i passi 5 e 6. La sintassi C non impone un ordine piuttosto che un altro.
Ma la differenza con il caso in studio precedente e' proprio qui.
A seconda dell'ordine di esecuzione si ottiene 0 oppure 1.

Black imp
13-03-2010, 15:28
scusate ma io mi soffermerei un attimo su concetti più di logica che non di implementazione:

sappiamo che il post incremento agisce DOPO l'assegnazione:

se fosse



int a = 0;
int b;

b = a++;


b varrebbe 0 e a varrebbe 1.

nel caso in esame si sta incrementando il simbolo a. come avvenga usualmente tradotta questa operazione in assembly non ha alcuna rilevanza per 'decidere' quale risultato sarebbe lecito aspettarsi.

morale: ho un operatore che incrementa DOPO l'assegnazione, e ho un simbolo ben preciso che viene incrementato ed è a. quindi per me il valore corretto dovrebbe essere 1.

cioè a livello logico io ho esplicitamente detto che il contenuto di a dopo l'assegnazione debba essere incrementato. non ho detto che a visto come parametro deve essere incrementato mentre la variabile a sx dell'assegnamento no. quella è una distinzione che fa l'implementazione del linguaggio, non la logica secondo me.

wingman87
13-03-2010, 15:54
No, il punto è che l'incremento non viene fatto dopo l'assegnazione, ma dopo aver valutato il valore della variabile. L'esempio di gugoXX spiega benissimo questo fatto.

Black imp
14-03-2010, 00:38
No, il punto è che l'incremento non viene fatto dopo l'assegnazione, ma dopo aver valutato il valore della variabile. L'esempio di gugoXX spiega benissimo questo fatto.

è lo stesso perché la valutazione della variabile è fatta per fare l'assegnazione. valuti, assegni, incrementi. l'esempio riportato invece conferma quanto dico. in quel caso l'operatore a sx è un operatore + anziché = ma la logica è la stessa: valuti sommi e incrementi, poi valuti sommi ancora e incrementi.

wingman87
14-03-2010, 00:49
è lo stesso perché la valutazione della variabile è fatta per fare l'assegnazione. valuti, assegni, incrementi. l'esempio riportato invece conferma quanto dico. in quel caso l'operatore a sx è un operatore + anziché = ma la logica è la stessa: valuti sommi e incrementi, poi valuti sommi ancora e incrementi.
Ma no, l'ordine è valuti, incrementi e sommi, riporto qui l'esempio di gugoXX:
1) Viene salvato temporaneamente il valore di a, ovvero 2.
2) a viene incrementato di uno. (che vale 3 quindi)
3) viene eseguita la somma tra 123 e il valore 2 salvato = 125
4) viene salvato temporaneamente il valore di a, ovvero 3.
5) viene incrementato il valore di a, che varra' quindi 4.
6) viene eseguita la somma tra 125 e 3 precedentemente salvato = 128, che viene assegnata a