PDA

View Full Version : Come legge il compilatore?


eraser
17-12-2005, 12:45
Domanda stupida :)

Il compilatore ha un verso di lettura del codice?

Quello che intendo è questo:

(if a==5 && b==8) , seguendo l'AND logico basta che una delle due sia falsa e l'if non viene controllato.....ma quale delle due espressioni viene controllata per prima? Qualcuno mi ha detto normalmente prima a e, se è vera, b; qualcun altro mi ha detto il contrario :muro:

Qual è la realtà? :)

Bane
17-12-2005, 12:58
Parlando del C presumo... =)
L'operatore && associa da sx verso dx, la verifica di un'espressione
termina non appena si e' stabilito se l'espressione e' falsa o vera.
Quindi, in questo caso, se (a == 5) e' falsa (b == 8) non viene
nemmeno valutata.

eraser
17-12-2005, 12:59
si scusa, parliamo di C :)

franksisca
17-12-2005, 15:52
Parlando del C presumo... =)
L'operatore && associa da sx verso dx, la verifica di un'espressione
termina non appena si e' stabilito se l'espressione e' falsa o vera.
Quindi, in questo caso, se (a == 5) e' falsa (b == 8) non viene
nemmeno valutata.
al 90% anche in java segue quella formula.
l'altro 10% è se ero ubriaco o no :D :D :D

17Qwerty71
17-12-2005, 16:45
puoi risponderti alla tua domanda provando ad inserire delle funzioni nella condizione :)

prova a fare:
if((getchar()=='a') && (getchar()=='a'))

71104
17-12-2005, 23:55
veramente a me sembra che non sia standard l'ordine di valutazione dei parametri, quindi viene lasciato libero all'implementazione per così dire. in genere naturalmente si valuta da sinistra verso destra.

Dun
18-12-2005, 01:21
Questo ragionamento l'avevo trovato per l'OR invece che per l'AND

Da qualche parte avevo letto che veniva utilizzato il cosiddetto "lazy OR" ovvero se la prima era vera allora non si controllava minimanente la seconda condizione. Questo ovviamente in ambito C.

A dir la verita mi son sempre fidato e non ho mai controllato esplicitamente.

17Qwerty71
18-12-2005, 01:43
Questo ragionamento l'avevo trovato per l'OR invece che per l'AND

Da qualche parte avevo letto che veniva utilizzato il cosiddetto "lazy OR" ovvero se la prima era vera allora non si controllava minimanente la seconda condizione. Questo ovviamente in ambito C.

A dir la verita mi son sempre fidato e non ho mai controllato esplicitamente.
Dipende dal compilatore, ma probabilmente se addotta questo sistema con l'OR lo addotta anche per l'AND (nel caso incontrasse una falsa).
Del resto sarebbe poi solo uno spreco di tempo controllare i successivi se si può gia conoscere il risultato della condizione.

Dun
18-12-2005, 05:23
Dipende dal compilatore, ma probabilmente se addotta questo sistema con l'OR lo addotta anche per l'AND (nel caso incontrasse una falsa).
Del resto sarebbe poi solo uno spreco di tempo controllare i successivi se si può gia conoscere il risultato della condizione.

Esattamente....adesso non mi ricordo esattamente ma mi pare che invece fosse dipendente addirittura dalle specifiche del linguaggio C....

Bane
18-12-2005, 11:50
veramente a me sembra che non sia standard l'ordine di valutazione dei parametri
A me, invece, risulta proprio standard.
L'esempio classico che in questi casi viene fatto e':

if ((p != NULL) && (p->qualcosa != qualcosaltro))

Sai che bello se valutasse i termini con un ordine
non standard o li valutasse sempre tutti... =)

Comportamento analogo per l'operatore ||.

Comunque, sinceramente, non ho voglia di andarmi a
spulciare lo standard per vedere se ricordo correttamente,
facciamo che ognuno si tiene le proprie convinzioni... =))

71104
18-12-2005, 13:27
scusa, ma mi permetto di ribadire :)
anche io conosco un esempio classico:

int i = 5;
printf("%d %d", i++, i--);

lo standard non dice quale sia l'output di quella cosa! ;)
sono però d'accordo sul fatto che molti compilatori valutano da sinistra verso destra (il Microsoft lo fa, l'Intel lo fa, e penso anche il gcc; direi che bastano :sofico: ).

Bane
18-12-2005, 13:54
Mah, forse non mi sono spiegato bene... O_o

Io ho risposto ad una domanda specifica, dicendo che in quel caso
(sequenza di &&/|| bla bla bla) la valutazione avviene in un certo modo
previsto dallo standard (da sx a dx e fermandosi quando bla bla bla).

Ripeto, non in generale, ma nel caso in esame!

Concordo invece che l'esempio da te riportato non e' regolato dallo
standard, ma non c'entra nulla con la domanda specifica del topic =)

Bane
18-12-2005, 14:49
PS: =)

Vabbe', alla fine la curiosita' ha vinto sulla mia bradiposita' per le ricerche... =)

Tratto da: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n869/


6.5.13 Logical AND operator

Syntax

[#1]

logical-AND-expr:
inclusive-OR-expr
logical-AND-expr && inclusive-OR-expr

Constraints

[#2] Each of the operands shall have scalar type.

Semantics

[#3] The && operator shall yield 1 if both of its operands
compare unequal to 0; otherwise, it yields 0. The result
has type int.

[#4] Unlike the bitwise binary & operator, the && operator
guarantees left-to-right evaluation; there is a sequence
point after the evaluation of the first operand. If the
first operand compares equal to 0, the second operand is not
evaluated.

71104
18-12-2005, 16:54
Concordo invece che l'esempio da te riportato non e' regolato dallo standard, ma non c'entra nulla con la domanda specifica del topic =) be', dovrebbe entrarci invece, visto che in C++ gli operatori sono funzioni... O.o
ad esempio, metti che tu ridefinisci una versione di operatore + (più): devi scrivere una vera e proprio funzione che si chiama "operator +", vuole in ingresso due parametri del tipo che ti pare a te, e restituisce un tipo che ti pare a te; l'ordine di valutazione dei parametri non è stabilito...

edit: ho letto quello che hai riportato: boh, non so che dire... O_o

The3DProgrammer
18-12-2005, 22:55
be', dovrebbe entrarci invece, visto che in C++ gli operatori sono funzioni... O.o
ad esempio, metti che tu ridefinisci una versione di operatore + (più): devi scrivere una vera e proprio funzione che si chiama "operator +", vuole in ingresso due parametri del tipo che ti pare a te, e restituisce un tipo che ti pare a te; l'ordine di valutazione dei parametri non è stabilito...

edit: ho letto quello che hai riportato: boh, non so che dire... O_o


Probabilmente è una precisazione necessaria, prevista proprio per le situazioni che ha descritto Bane. Personalmente conoscevo tale approccio col nome di cortocircuito.

ciau

sottovento
19-12-2005, 09:20
- In C, e' standard la modalita' "Short Circuit", per cui viene valutata la parte di espressione necessaria a determinare il risultato. Essendo comunque presenti sul mercato un'infinita' di compilatori per tutte le piattaforme possibili, non ci farei sempre affidamento e farei un controllo preliminare;

- In Java e' possibile avere entrambe le modalita': l'operatore && ritornera' la valutazione short circuit, l'operatore "bitwise" & (o meglio, e' un operatore bitwise su interi) ritornera' la valutazione "lunga" sui booleani. La stessa cosa puo' essere simulata, con un minimo di attenzione, in C.

Per esempio (Java):

public class Test
{
private static boolean a()
{
System.out.println ("Chiamo A");
return false;
}
private static boolean b()
{
System.out.println ("Chiamo B");
return true;
}

public static void main (String[] args)
{
if (a() && b())
System.out.println ("Risultato AND (Short Circuit) TRUE");
else
System.out.println ("Risultato AND (Short Circuit) FALSE");

if (a() & b())
System.out.println ("Risultato AND TRUE");
else
System.out.println ("Risultato AND FALSE");
}
}

High Flying
Sottovento

cdimauro
19-12-2005, 14:17
Che io sappia, in C vale sempre la Shor Circuit evaluation degli argomenti "booleani": tutti i compilatori devono attenersi a questa regola, altrimenti escono fuori dallo standard.

pipozzolo
21-12-2005, 14:30
Che io sappia, in C vale sempre la Shor Circuit evaluation degli argomenti "booleani": tutti i compilatori devono attenersi a questa regola, altrimenti escono fuori dallo standard.

Esatto! Ma non solo in C
Pensate che bello se fate un controllo in java tipo:

if(oggetto != null && !oggetto.equals("")) {
}

è ovvio che se la prima è falsa la seconda non viene valutata, altrimenti darebbe una poco simpatica NullPointerException.

Poi per il passaggio di parametri alle funzioni, il discorso è diverso, ma per gli operatori logici è assolutamente così.

Per le funzioni sono quasi certo che la valutazione sia obbligatoriamente da sinistra a destra, quindi printf("%d %d", i++, i--); se i vale 5 sarebbe printf("%d %d", 5, 6);

wisher
21-12-2005, 21:56
Domanda stupida :)

Il compilatore ha un verso di lettura del codice?

Quello che intendo è questo:

(if a==5 && b==8) , seguendo l'AND logico basta che una delle due sia falsa e l'if non viene controllato.....ma quale delle due espressioni viene controllata per prima? Qualcuno mi ha detto normalmente prima a e, se è vera, b; qualcun altro mi ha detto il contrario :muro:

Qual è la realtà? :)
ho una piccola curiosità: questo problema te lo poni solo a livello concettuale o vorresti giungere a qualche ottimizzazione anche sulle singole operazioni logiche?

cdimauro
22-12-2005, 08:26
Esatto! Ma non solo in C
Pensate che bello se fate un controllo in java tipo:

if(oggetto != null && !oggetto.equals("")) {
}

è ovvio che se la prima è falsa la seconda non viene valutata, altrimenti darebbe una poco simpatica NullPointerException.
Esattamente. Ed è una gran comodità. :)
Poi per il passaggio di parametri alle funzioni, il discorso è diverso, ma per gli operatori logici è assolutamente così.

Per le funzioni sono quasi certo che la valutazione sia obbligatoriamente da sinistra a destra, quindi printf("%d %d", i++, i--); se i vale 5 sarebbe printf("%d %d", 5, 6);
Non è così: lo standard dice chiaramente che l'ordine di valutazione degli argomenti non è fissato, quindi dipende dal compilatore.

In molti testi trovi anche l'esempietto che se vuoi essere sicuro che un'espressione dev'essere valutata prima di un'altra, devi per forza di cose valutarla per prima:
j = i++;
printf("%d %d", j, i--);
per l'esempio che hai portato. :)

sottovento
22-12-2005, 09:16
Ribadisco. In Java hai entrambe le possibilita':

if (a && b) ...
Se a e' false, allora non si proseguira' nella valutazione (valutazione short circuit)

if (a & b)
Vengono valutate entrambe le espressioni

High Flying
Sottovento

pipozzolo
22-12-2005, 10:06
Esattamente. Ed è una gran comodità. :)

Non è così: lo standard dice chiaramente che l'ordine di valutazione degli argomenti non è fissato, quindi dipende dal compilatore.

In molti testi trovi anche l'esempietto che se vuoi essere sicuro che un'espressione dev'essere valutata prima di un'altra, devi per forza di cose valutarla per prima:
j = i++;
printf("%d %d", j, i--);
per l'esempio che hai portato. :)

Hai ragione, mi sono confuso con Java nel quale l'ordine è definito :stordita:

pipozzolo
22-12-2005, 10:14
Ribadisco. In Java hai entrambe le possibilita':

if (a && b) ...
Se a e' false, allora non si proseguira' nella valutazione (valutazione short circuit)

if (a & b)
Vengono valutate entrambe le espressioni

High Flying
Sottovento

E' vero... occhio però ad un particolare:

int a = 1;
if(a++ > 0 && a != 2) ti da false

mentre
if(a++ > 0 & a != 2) ti da true

questo perchè gli operatori bitwise (non essendo operatori logici) vengono valutati normalmente (da destra verso sinistra).

sottovento
22-12-2005, 11:15
E' vero... occhio però ad un particolare:

int a = 1;
if(a++ > 0 && a != 2) ti da false

mentre
if(a++ > 0 & a != 2) ti da true

questo perchè gli operatori bitwise (non essendo operatori logici) vengono valutati normalmente (da destra verso sinistra).

Scusa, ma io ho provato (jdk 1.4.1_02) e mi da false in entrambi i casi. Non e' che ti sei dimenticato di rimettere a=1?

Ad ogni modo, questa e' una di quelle situazioni da evitare.

Un'ultima osservazione: Java ha il tipo booleano e l'operatore "&" non e' quindi il bitwise su interi. Si tratta proprio di un nuovo operatore, diversamente dal linguaggio C/C++.