Newsgroup: it.comp.lang.c++
Titolo: Vantaggio sconosciuto di java vs c++

leggete qui, ciò che dice riguardo ai bool
http://www.perryland.com/Java2.shtml
io sapevo che non era così, sapevo che scrivendo 
if (a || b)
b non veniva valutato se a era già true...
ricordo male?
-- 
]\/[ad]\/[age (
www.mindreamz.net
)
"Un Maestro insegue semplicemente la sua visione di Eccellenza in
qualunque cosa sta facendo e lascia agli altri decidere se sta 
lavorando o giocando. A lui sembra sempre di fare entrambe." - Anonimo

 ricordo male?
Forse, ma non sono sicuro, lo standard non definisce come l'espressione
debba essere valutata. Se è così dipende dal compilatore..

 ricordo male?
Ricordi bene.
Max

b non veniva valutato se a era già true...
   Infatti la pagina che hai si riferisce al caso 'if (a | b)', e
comunque non concordo con la loro assunzione che l'or e l'and binario
non siano mai cortocircuitabili in C/C++.
-- 
S.L.

non siano mai cortocircuitabili in C/C++.
Or e and binari (|,&) *non* usano la logica short circuit
in C++; sono solo or e and logico (||,&&) che la usano.
Comunque quello che e' detto nel sito e' una fesseria in ogni
caso: sottolineare che il C++ non ha un tipo boolean (falso)
e dire che questo comporta che non viene fatta la valutazione
short circuit (falso) significa che chi ha scritto quelle
note di C++ non sa nulla.
Qualcosa che purtoppo capita spesso su internet (ma anche su
articoli di riviste "specializzate" - almeno qui in italia).
:(
Andrea

 in C++; sono solo or e and logico (||,&&) che la usano.
Cosa si intende per "logica short circuit"? Se non ti dispiace potresti
spiegarlo?

...

Il fatto che nelle espressioni
a || b
c && d
b e d sono calcolati solo se necessario. In particolare se a e' vero b
non e' calcolato, cosi' come se c e' falso d non e' calcolato.
Ciao,
Nicola

 spiegarlo?
Semplicemente che la valutazione dell'espressione logica
procede FINO AL PUNTO in cui il suo valore di verità (true|false)
è inequivocabilmente definito.
Ad esempio: l'AND logico restituisce false quando ALMENO UNO
dei due operandi è false. Quindi nella valutazione dell'espressione
A && B, se A è false l'intera espressione vale false e B può non
essere valutato.
Analogamente nel caso dell'OR, quando il primo operando
vale true, è determinato il valore dell'intera espressione, dunque
non si procede oltre.
Così funziona il C e il C++.
Attenzione però... 
Proprio la possibile mancata valutazione delle espressioni rimanenti
può non essere affatto equivalente ai fini dello stato del programma
(al di là del diverso ramo di esecuzione selezionato dal codice)
se uno dei due operandi ha effetti collaterali.
Ad es:
int a, b;
...
if(a < 2 || ++b > 3)
{
// qui b è incrementato o meno a seconda che a sia o meno < 2
...
}

 }
Grazie ad entrambi

 ricordo male?
A onor del vero, nel contesto l'articolo non dice che il C++ si comporti in 
modo diverso, ma nemmeno che si comporti allo stesso modo (che sarebbe la 
verità).
Essendo uno stralcio che si prefigge il confronto fra i due linguaggi, è 
comunque una cazzata perchè lascia intendere la cosa sbagliata (come 
giustamente hai osservato).
 

 spiegarlo?
Significa formalmente: gli operatori logici vengono valutati da sinistra a 
destra e la valutazione si interrompe quando il risultato dell'intera 
espressione è definito.
All'atto pratico significa che nell'espressione
a || b
se a è vero b non viene valutato 
ancora un esempio più pratico:
a || someFunction()
someFunction() viene invocata solo se a è falso (e quì capisci meglio 
l'importanza di sapere ordine e metodo di valutazione)
infine ultimo esempio:
(a != NULL) && (a->someMember())
hai garantito dalla logica shortcircuit che il programma non crasherà per 
l'uso del puntatore nullo.

 espressione è definito.
A voler essere rigorosi (e fors'anche corretti) l'ordine
di valutazione degli operandi, determinato dalvalore dell'associatività
(sinistra|destra) dell'operatore, prescinde dalla politica
di shor-circuit.
La logica a valutazione minimale, come potremmo genericamente definirla,
funzionerebbe altrettanto bene se si valutassero
le espressioni di un AND o di un OR logico da destra a sinistra,
con effetti collaterali evidentemente diversi, a parità di espressione.
Ciao.

 espressione è definito.
A voler essere rigorosi (e fors'anche corretti) l'ordine


con effetti collaterali evidentemente diversi, a parità di espressione.
Non capisco il senso di questo tuo post.
In C++ per and e or logico viene garantita la valutazione
sinistra->destra con il secondo operando che viene valutato
solo se il valore del primo non basta per sapere il risultato.
Questo permette ad esempio di scrivere cose come
  if (x>=0 && v[x]!=3)
     ...
senza dover aver paura che v[x] venga valutato per valori
negativi della x (cosa che creerebbe problemi).
L'associativita' a sinistra inoltre dice che
  a && b && c && d && e
significa
  (((a && b) && c) && d) && e
e quindi implica che i vari operandi saranno in questa
espressione considerati in ordine da sinistra a destra
sino al primo che restituisce "falso".
L'uso di una valutazione short-circuit equivalente ma con
ordinamento da destra a sinistra risulterebbe molto innaturale
(almeno per la nostra cultura).
Al di fuori di &&, || e dell'operatore "virgola" il C++ e'
invece libero di scegliere l'ordine di valutazione come
meglio crede e non e' in nessun caso autorizzato 'semplificare'
dei calcoli saltando delle valutazioni. Ad esempio:
  int x = 0;
  int y = x * f(); // La funzione f *DEVE* essere chiamata
                   // anche se il suo risultato sara' poi
                   // moltiplicato per zero
Inoltre se scrivo
   z = f()*g()+h();
o anche
   std::cout << f() << g() << h();
non posso prevedere quale fra le funzioni f,g o h sara'
chiamata per prima.
HTH
Andrea

 sino al primo che restituisce "falso".
Ti dò perfettamente ragione.
E' chiaro che l'ordine di valutazione DEVE essere noto a priori.
E che, per ragioni eminentemente culturali, educati e abituati come
siamo a leggere caratteri, ma anche immagini, da sinistra a destra
l'associatività
da sinistra a destra è + la più naturale.
Ciò non toglie che la valutazione short-circuit(ly) di espressioni
logiche si fonda sul principio di un valore di verità determinato da
un sottoinsieme minimo di operandi. Chiaramente, torno a ripetere,
l'individuazione di tale insieme deve sottostare a regole note:
la citata associatività.
Ciao.

                    // moltiplicato per zero
A voler essere pignoli il programma deve comportarsi *come se* la
funzione f fosse chiamata; in altre parole f deve essere chiamata se
ha effetti collaterali osservabili.
Ciao,
Nicola

ha effetti collaterali osservabili.
Questa e' una obiezione che ogni tanto qualcuno fa e che
e' pero' secondo me priva di senso.
Il programma deve chiamare la funzione, ovvero non deve
essere possibile dire tramite alcuna osservazione a
livello C++ che non e' stata chiamata.
Cosa significa quindi dire che potrebbe anche non essere
chiamata se non puoi provare che non e' stata chiamata ?
Se poi consideriamo la cosa da un punto di vista pratico
e con l'attuale impostazione dei compilatori che sono
pensati per lavorare con la visibilita' di un solo
modulo per volta; anche di fronte a funzioni che banalmente
non producono alcun effetto osservabile il compilatore sara'
costretto a generare la chiamata (semplicemente perche'
quando compila la chiamata non ha modo di sapere come
e' fatta la funzione).
Questi sono i motivi per cui ritengo questa invocazione
della regola d'oro "come-se" privi di significato non solo
da un punto di vista pratico, ma anche concettuale.
Riassumendo... se c'e' una differenza allora il compilatore
deve chiamare la funzione. Se non c'e' differenza come fai
a dire che e' stata chiamata o no ?
Dire che potrebbe non chiamarla se non c'e' differenza
secondo me e' solo fare confusione.
Andrea

 Nicola
Ciao.

 possibili. Non mi pare una cosa da poco.
Infatti nessun compilatore affronta il problema nel caso generale;
esistono pero' casi particolari che sono perfettamente gestibili. Il
primo esempio che mi viene in mente e' il caso in cui la funzione
coinvolta sia dichiarata inline.
Ciao,
Nicola

 espressione. 
Assolutamente no. Non scherziamo.
Nell'espressione:
(a != NULL) && (a->someMember())
è scritta in quel modo perchè SO che l'ordine di valutazione è quello e la 
regola dello short-circuit è rispettata. Se l'ordine di valutazione fosse 
inverso quel programma *non* *funzionerebbe* e il crash non sarebbe un 
"effetto collaterale evidentemente diverso".

 "effetto collaterale evidentemente diverso".
Leggiti PRIMA tutti i post.

 Chiaramente non hai compreso l'essenza delle mie affermazioni.
L'essenza? Può darsi. Il significato si, però <g>