C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

if or ...comment faire
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
giovanni
Guest





PostPosted: Mon Feb 14, 2005 7:50 am    Post subject: if or ...comment faire Reply with quote



pour evite de faire tout les if a peine un if e vraie va au (a=a+1 etc)
et puis difference if ..... {.......}
et
if .... then ....... endif
merci
me fais erreur ce code la ! (59 E:sauveDev-Cpptest.cpp syntax error
before `||' token etc
if (nb_22==nb_8) || nb_22==nb_2 || nb_22==nb_3
Quote:
nb_22==nb_4|| nb_22==nb_5|| nb_22==nb_6|| nb_22==nb_7) then
{a=a+1;

b=b+1;}



Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Feb 14, 2005 8:19 am    Post subject: Re: if or ...comment faire Reply with quote



giovanni wrote:
Quote:
pour evite de faire tout les if a peine un if e vraie va au
(a=a+1 etc) et puis difference if ..... {.......}
et
if .... then ....... endif
merci
me fais erreur ce code la ! (59 E:sauveDev-Cpptest.cpp syntax
error
before `||' token etc
if (nb_22==nb_8) || nb_22==nb_2 || nb_22==nb_3
| nb_22==nb_4|| nb_22==nb_5|| nb_22==nb_6|| nb_22==nb_7) then
{a=a+1;
b=b+1;}

Tu penses programmer dans quel langage ? Parce que j'ai
l'impression que c'en est un melange de plusieurs. Dans les
langages de la famille C, il n'y a pas de « then » -- le syntaxe
d'un if est :

if ( <condition )
Dans ton code, 1) tu fermes les parenthèses après la première
comparaison, ce qui signifie la fin de la condition -- le || est
pris comme le début du <statement>, et il n'y a pas de statement
qui puisse commencer par un ||, et 2) tu as mis un then à la
fin.

Je dirais un langage de la famille Pascal, sauf que les || et
les == sont typique de la famille C, et n'existe pas dans les
langages de la famille Pascal.

Il faut choisir un langage, puis l'apprendre.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Back to top
korchkidu
Guest





PostPosted: Mon Feb 14, 2005 8:27 am    Post subject: Re: if or ...comment faire Reply with quote



giovanni wrote:

Quote:
pour evite de faire tout les if a peine un if e vraie va au (a=a+1 etc)
et puis difference if ..... {.......}
et
if .... then ....... endif
merci
me fais erreur ce code la ! (59 E:sauveDev-Cpptest.cpp syntax error
before `||' token etc
if (nb_22==nb_8) || nb_22==nb_2 || nb_22==nb_3
| nb_22==nb_4|| nb_22==nb_5|| nb_22==nb_6|| nb_22==nb_7) then
{a=a+1;
b=b+1;}



Il manque les parentheses (entre autres...):

if ((nb_22==nb_8) || (nb_22==nb_2) || (nb_22==nb_3)
Quote:
(nb_22==nb_4) || (nb_22==nb_5) || (nb_22==nb_6) || (nb_22==nb_7))
{

a=a+1;
b=b+1;
}

Par contre, si je peux me permettre, toutes tes variables nb_** ne
pourraient-elles pas etre stockees dans un tableau?

K.

Back to top
giovanni
Guest





PostPosted: Mon Feb 14, 2005 3:33 pm    Post subject: Re: if or ...comment faire Reply with quote

merci je vais essayer
pour gaby et bien j'ai commencer avec le basic ensuite du pascal et visual
basic aussi maintenant fini au c++
c'est vrai je suis pas programmeur de metier je me amuse disons petit
utilitaire pour moi
je suis italien et je vis en suisse romande mais c'est vrai je suis pas fort
en francais....
j'aurai du mettre en tableau oui mais encore debutant pour ca ca sera une
optimse plus tard...
le or ||
et le or |
quel difference?
merci




"korchkidu" <korch_ki_du (AT) yahoo (DOT) fr> a écrit dans le message de news:
4210610a$1 (AT) epflnews (DOT) epfl.ch...
Quote:
giovanni wrote:

pour evite de faire tout les if a peine un if e vraie va au (a=a+1 etc)
et puis difference if ..... {.......}
et
if .... then ....... endif
merci
me fais erreur ce code la ! (59 E:sauveDev-Cpptest.cpp syntax error
before `||' token etc
if (nb_22==nb_8) || nb_22==nb_2 || nb_22==nb_3
| nb_22==nb_4|| nb_22==nb_5|| nb_22==nb_6|| nb_22==nb_7) then
{a=a+1;
b=b+1;}



Il manque les parentheses (entre autres...):

if ((nb_22==nb_8) || (nb_22==nb_2) || (nb_22==nb_3)
| (nb_22==nb_4) || (nb_22==nb_5) || (nb_22==nb_6) || (nb_22==nb_7))
{
a=a+1;
b=b+1;
}

Par contre, si je peux me permettre, toutes tes variables nb_** ne
pourraient-elles pas etre stockees dans un tableau?

K.



Back to top
Vincent Lascaux
Guest





PostPosted: Mon Feb 14, 2005 4:13 pm    Post subject: Re: if or ...comment faire Reply with quote

Quote:
le or ||
et le or |
quel difference?

est un opérateur binaire, le résultat de a | b est le résultat obtenu en
faisant un ou bit à bit des valeurs
| est un opérateur booléen. Je peux me tromper, mais je pense que la seule
chose qui est garantie, c'est que a || b == 0 si et seulement si a==0 ou b

== 0 (si ce n'est pas le cas, je ne pense pas que la norme ne donne aucune
indication sur la valeur de a || b (hors mis le fait que c'est non nul)).

Pour | et || la différence n'est pas fondammentalle étant donnée qu'on peut
utiliser | à la place de || (d'ailleurs je suppose que sur beaucoup de
compilateurs, || est équivalent à |)
Ce n'est pas le cas pour & et && : 2 & 4 == 0 et la norme garantie que 2 &&
4 est non nul

--
Vincent



Back to top
Bertrand Motuelle
Guest





PostPosted: Tue Feb 15, 2005 9:03 am    Post subject: Re: if or ...comment faire Reply with quote

Vincent Lascaux wrote:
Quote:
le or ||
et le or |
quel difference?

| est un opérateur binaire, le résultat de a | b est le résultat
obtenu en
faisant un ou bit à bit des valeurs
|| est un opérateur booléen. Je peux me tromper, mais je pense que
la seule
chose qui est garantie, c'est que a || b == 0 si et seulement si a==0
ou b
== 0 (si ce n'est pas le cas, je ne pense pas que la norme ne donne
aucune
indication sur la valeur de a || b (hors mis le fait que c'est non
nul)).

Pour | et || la différence n'est pas fondammentalle étant donnée
qu'on peut
utiliser | à la place de || (d'ailleurs je suppose que sur beaucoup
de
compilateurs, || est équivalent à |)

Il y a une différence fondamentale: || court-circuite l'évaluation de
l'opérande de droite si celle de gauche est vraie (true || x == true)

Quote:
Ce n'est pas le cas pour & et && : 2 & 4 == 0 et la norme garantie
que 2 &&
4 est non nul

De même && court-circuite l'évaluation de l'opérande de droite si
celle de gauche est fausse (false && x == false)

a+
Bertrand.


Back to top
Pierre Maurette
Guest





PostPosted: Tue Feb 15, 2005 9:55 am    Post subject: Re: if or ...comment faire Reply with quote

Vincent Lascaux a écrit :
Quote:
le or ||
et le or |
quel difference?


| est un opérateur binaire, le résultat de a | b est le résultat obtenu en
faisant un ou bit à bit des valeurs
|| est un opérateur booléen. Je peux me tromper, mais je pense que la seule
chose qui est garantie, c'est que a || b == 0 si et seulement si a==0 ou b
== 0 (si ce n'est pas le cas, je ne pense pas que la norme ne donne aucune
indication sur la valeur de a || b (hors mis le fait que c'est non nul)).
Si si. La norme garantit la valeur 1. Une évaluation logique ne peut

conduire qu'à 0 ou 1. C'est le contraire qui n'est pas vrai: une valeur
non nulle est considérée comme vraie même si différente de 1. Ainsi:
a = (a || a) normalise la valeur da a en booléen (0 ou 1). Comme
a = (a && a)
et quelques autres.

Quote:
Pour | et || la différence n'est pas fondammentalle étant donnée qu'on peut
utiliser | à la place de || (d'ailleurs je suppose que sur beaucoup de
compilateurs, || est équivalent à |)
Ce n'est pas le cas pour & et && : 2 & 4 == 0 et la norme garantie que 2 &&
4 est non nul
AMHA, confondre

(nb_22==nb_3) | (nb_22==nb_4)
et
(nb_22==nb_3) ||(nb_22==nb_4)
est toujours une erreur. D'abord, il faut coder au plus près de la
logique, or, | est un opérateur arithmétique et || un opérateur logique.
De plus, je ne pense pas que la règle de l'évaluation économique
(incomplète) soit appliquée à l'opérateur |:
if(exprA || exprB)
n'évaluera pas exprB si exprA est vraie. Je ne pense pas que ce soit le
cas de:
if(exprA | exprB)
Disons plutôt que l'évaluation de G à D et incomplète ne sont pas
garanties par la norme. C'est alors l'optimisation qui décide. Ce qui
peut avoir avantages ou inconvénients, mais là n'est pas la question.
--
Pierre

Back to top
giovanni
Guest





PostPosted: Tue Feb 15, 2005 11:58 am    Post subject: Re: if or ...comment faire Reply with quote

merci
"Pierre Maurette" <maurettepierre (AT) wanadoo (DOT) fr> a écrit dans le message de
news: [email]37dv8bF5bcm7fU1 (AT) individual (DOT) net[/email]...
Quote:
Vincent Lascaux a écrit :
le or ||
et le or |
quel difference?


| est un opérateur binaire, le résultat de a | b est le résultat obtenu
en faisant un ou bit à bit des valeurs
|| est un opérateur booléen. Je peux me tromper, mais je pense que la
seule chose qui est garantie, c'est que a || b == 0 si et seulement si
a==0 ou b == 0 (si ce n'est pas le cas, je ne pense pas que la norme ne
donne aucune indication sur la valeur de a || b (hors mis le fait que
c'est non nul)).
Si si. La norme garantit la valeur 1. Une évaluation logique ne peut
conduire qu'à 0 ou 1. C'est le contraire qui n'est pas vrai: une valeur
non nulle est considérée comme vraie même si différente de 1. Ainsi:
a = (a || a) normalise la valeur da a en booléen (0 ou 1). Comme
a = (a && a)
et quelques autres.

Pour | et || la différence n'est pas fondammentalle étant donnée qu'on
peut utiliser | à la place de || (d'ailleurs je suppose que sur beaucoup
de compilateurs, || est équivalent à |)
Ce n'est pas le cas pour & et && : 2 & 4 == 0 et la norme garantie que 2
&& 4 est non nul
AMHA, confondre
(nb_22==nb_3) | (nb_22==nb_4)
et
(nb_22==nb_3) ||(nb_22==nb_4)
est toujours une erreur. D'abord, il faut coder au plus près de la
logique, or, | est un opérateur arithmétique et || un opérateur logique.
De plus, je ne pense pas que la règle de l'évaluation économique
(incomplète) soit appliquée à l'opérateur |:
if(exprA || exprB)
n'évaluera pas exprB si exprA est vraie. Je ne pense pas que ce soit le
cas de:
if(exprA | exprB)
Disons plutôt que l'évaluation de G à D et incomplète ne sont pas
garanties par la norme. C'est alors l'optimisation qui décide. Ce qui peut
avoir avantages ou inconvénients, mais là n'est pas la question.
--
Pierre



Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Tue Feb 15, 2005 12:30 pm    Post subject: Re: if or ...comment faire Reply with quote

Pierre Maurette wrote:
Quote:
Vincent Lascaux a écrit :
le or ||
et le or |
quel difference?

| est un opérateur binaire, le résultat de a | b est le
résultat obtenu en faisant un ou bit à bit des valeurs ||
est un opérateur booléen. Je peux me tromper, mais je pense
que la seule chose qui est garantie, c'est que a || b == 0
si et seulement si a==0 ou b == 0 (si ce n'est pas le cas,
je ne pense pas que la norme ne donne aucune indication sur
la valeur de a || b (hors mis le fait que c'est non nul)).

Si si. La norme garantit la valeur 1.

Pas tout à fait. La norme garantit la valeur true, non 1. Le
résultat est de type bool. Mais évidemment, si on convertit le
résultat en un type entier autre que bool, le résultat de la
conversion est garanti d'être 1.

Quote:
Une évaluation logique ne peut conduire qu'à 0 ou 1.

À false ou à true.

Quote:
C'est le contraire qui n'est pas vrai: une valeur non nulle
est considérée comme vraie même si différente de 1.

Là aussi, il s'agit d'une conversion.

Quote:
Ainsi:
a = (a || a) normalise la valeur da a en booléen (0 ou 1). Comme
a = (a && a)
et quelques autres.

Pour | et || la différence n'est pas fondammentalle étant
donnée qu'on peut utiliser | à la place de || (d'ailleurs je
suppose que sur beaucoup de compilateurs, || est équivalent
à |)

Ce n'est pas le cas pour & et && : 2 & 4 == 0 et la norme
garantie que 2 && 4 est non nul

AMHA, confondre
(nb_22==nb_3) | (nb_22==nb_4)
et
(nb_22==nb_3) ||(nb_22==nb_4)
est toujours une erreur.

Probablement. Déjà, le résultat n'a pas le même type. Dans le
premier cas, il y a une promotion entière qui fait que
l'opération se ferait sur des int, avec un résultat int. Dans le
deuxième cas, l'opération se fait directement sur des bool, avec
un résultat bool.

La différence se fait sentir dès qu'il y a surcharge de
fonction, y compris des surcharges dus aux templates. Donc :

std::cout << std::boolalpha << (nb_22==nb_3) | (nb_22==nb_4) <<
'n' ;
std::cout << std::boolalpha << (nb_22==nb_3) || (nb_22==nb_4) <<
'n' ;

va sortir :
1
true

Quote:
D'abord, il faut coder au plus près de la logique, or, | est
un opérateur arithmétique et || un opérateur logique.

Sauf que c'est un drôle d'arithmétique. | est un opérateur
bit-à-bit, et || est un opérateur logique.

Quote:
De plus, je ne pense pas que la règle de l'évaluation
économique (incomplète) soit appliquée à l'opérateur |:

Pas du tout.

Quote:
if(exprA || exprB)
n'évaluera pas exprB si exprA est vraie. Je ne pense pas que
ce soit le cas de:
if(exprA | exprB)

Disons plutôt que l'évaluation de G à D et incomplète ne sont
pas garanties par la norme. C'est alors l'optimisation qui
décide.

Le comportement visible du programme doit être comme si les deux
ont été évalué. C'est garanti par la norme. (Donc, si exprB a
des effets de bord, ils auront lieu, quelque soit la valeur de
exprA.) En revanche, l'ordre de l'évaluation n'est pas
spécifié@; si exprA et exprB ont des effets de bord, on ne sait
pas dans quel ordre ils auront lieu.

Avec ||, en revance, on est garanti :

-- que le résultat est un bool,

-- que l'expression à gauche est complètement évaluée avant
qu'on commence l'évaluation de l'expression à droite,

-- qu'il y a court-circuit, c-à-d que si exprA est vrai, exprB
n'est pas évalué, et

-- qu'il y a un point de séquencement à l'opérateur, c-à-d que
je peux utiliser des objets dans exprB que j'ai modifié dans
exprA.

C'est même courant d'écrire des choses comme :
if ( p != NULL && p->valeur == x ) ...
Sans le court-circuit, il y aurait un comportement indéfini.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Back to top
Pierre Maurette
Guest





PostPosted: Tue Feb 15, 2005 1:29 pm    Post subject: Re: if or ...comment faire Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] a écrit :
Quote:
Pierre Maurette wrote:
[...]

Au temps pour moi. J'étais une fois de plus dans un contexte C et non
C++ (ou C99), d'où les (0,1) à la place de (false, true).

Ceci dit, le bool me pose problème même en C++, et sauf erreur de ma
part il masque un danger, pour le débutant ou le programmeur venant d'un
langage dans lequel le booléen est un vrai type.
Il est naturel, du moins tentant, d'écrire:
if((options&PorteAOuverte) == (options&PorteBOuverte)){}
En C++, est-ce le bug, ou pas ? Ou bien faut-il faire:
if((options&PorteAOuverte != false) == (options&PorteBOuverte != false)){}
?

Quote:
D'abord, il faut coder au plus près de la logique, or, | est
un opérateur arithmétique et || un opérateur logique.


Sauf que c'est un drôle d'arithmétique. | est un opérateur
bit-à-bit, et || est un opérateur logique.
J'ai toujours considéré les opérateurs bitwise comme des opérateurs

arithmétiques. & est à + la même chose que * est à +. C'est à dire que &
appliqué à deux données du même type entier fournit un résultat de ce
même type. Mais peu importe le nom.
En revanche, && entre deux int ne devrait pas exister dans un langage
rigoureux. Pour l'admettre, il faut avoir une certaine culture du C
(C++). Ce qui n'est pas une critique, mais la prise en compte d'une
réalité (si C et C++ étaient de mauvais langages, ça se saurait. S'ils
étaient parfaits également).

[...]
Quote:
if(exprA || exprB)
n'évaluera pas exprB si exprA est vraie. Je ne pense pas que
ce soit le cas de:
if(exprA | exprB)


Disons plutôt que l'évaluation de G à D et incomplète ne sont
pas garanties par la norme. C'est alors l'optimisation qui
décide.


Le comportement visible du programme doit être comme si les deux
ont été évalué. C'est garanti par la norme. (Donc, si exprB a
des effets de bord, ils auront lieu, quelque soit la valeur de
exprA.) En revanche, l'ordre de l'évaluation n'est pas
spécifié@; si exprA et exprB ont des effets de bord, on ne sait
pas dans quel ordre ils auront lieu.
Pour le court-circuit, pas de problème. C'est même ce que j'ai essayé

d'expliquer. En revanche, j'ai un problème justement avec:
if(exprA & exprB)
même question avec
if(exprA * exprB)
étant entendu que je préfèrerais écrire:
if((exprA & exprB) != 0)
et
if((exprA * exprB) != 0)
Si (par exemple) exprA est évaluée à 0, dans quels cas suis-je certain
que exprB sera évaluée ? Tout le temps ? Quand elle contient des appels
de fonctions ? Quand elle contient des variables déclarées volatile ?
Question subsidiaire: j'imagine que si l'évaluation de exprA modifie
celle de exprB (ou le contraire), j'ai un comportement indéfini, et donc
que je dois éviter (à la différence d'un && qui me permet de prévoir).
Eviter ou modifier, par exemple:
int tempo;
if((tempo = exprA) != 0)
if(exprB != 0)
Vrai ?
--
Pierre









Back to top
Falk Tannhäuser
Guest





PostPosted: Tue Feb 15, 2005 3:10 pm    Post subject: Re: if or ...comment faire Reply with quote

Pierre Maurette wrote:
Quote:
Ceci dit, le bool me pose problème même en C++, et sauf erreur de ma
part il masque un danger, pour le débutant ou le programmeur venant d'un
langage dans lequel le booléen est un vrai type.
Il est naturel, du moins tentant, d'écrire:
if((options&PorteAOuverte) == (options&PorteBOuverte)){}

Là, la comparaison se fera entre les entiers résultantes de
l'opération "et bit-à-bit".
S'il s'agit de comparer deux valeurs booléennes, ça sera plutôt :

if( ( (options & PorteAOuverte) != 0 ) ==
( (options & PorteBOuverte) != 0 ) ) {}

Quote:
En C++, est-ce le bug, ou pas ? Ou bien faut-il faire:
if((options&PorteAOuverte != false) == (options&PorteBOuverte !=false)){}

Pour des raisins hystériques, "==" et "!=" sont plus
prioritaires que "&" et "|" :-(

Quote:
Pour le court-circuit, pas de problème. C'est même ce que j'ai essayé
d'expliquer. En revanche, j'ai un problème justement avec:
if(exprA & exprB)
même question avec
if(exprA * exprB)
étant entendu que je préfèrerais écrire:
if((exprA & exprB) != 0)
et
if((exprA * exprB) != 0)

C'est ce que je préfère également ! Dans la mesure du possible,
j'évite de faire intervenir les conversions implicites entre
bool et les autres types intégraux (dans les deux sens) ainsi
que la conversion "pointeur vers bool" - sauf dans les cas
où l'emploi d'une telle conversion peut être considéré comme
idiomatique, comme dans
std::string line; while(std::getline(std::cin, line)) ...
plutôt que
while(std::getline(std::cin, line) != NULL)

Quote:
Si (par exemple) exprA est évaluée à 0, dans quels cas suis-je certain
que exprB sera évaluée ? Tout le temps ? Quand elle contient des appels
de fonctions ? Quand elle contient des variables déclarées volatile?

Rien dans la Norme semble permettre une évaluation court-circuit
pour les opérateurs autres que "&&", "||", "?:" (et encore,
l'évaluation court-circuit n'a lieu que tant qu'on n'appelle pas
une version surchargée des opérateurs "&&" ou "||").

Falk

Back to top
Pierre Maurette
Guest





PostPosted: Tue Feb 15, 2005 4:05 pm    Post subject: Re: if or ...comment faire Reply with quote

Falk Tannhäuser a écrit :
Quote:
Pierre Maurette wrote:

Ceci dit, le bool me pose problème même en C++, et sauf erreur de ma
part il masque un danger, pour le débutant ou le programmeur venant
d'un langage dans lequel le booléen est un vrai type.
Il est naturel, du moins tentant, d'écrire:
if((options&PorteAOuverte) == (options&PorteBOuverte)){}


Là, la comparaison se fera entre les entiers résultantes de
l'opération "et bit-à-bit".
S'il s'agit de comparer deux valeurs booléennes, ça sera plutôt :

if( ( (options & PorteAOuverte) != 0 ) ==
( (options & PorteBOuverte) != 0 ) ) {}
Bien sûr. C'était pour montrer un piège (de débutant, OK). Dans mon

idée, options est un paramètre du type C1 | C2 | .. | Cn, avec Cx des
constantes puissances de 2. PorteAOuverte et PorteBOuverte sont des Cx.
Le reproche que je fais aux bool du C++ et du C99 (et C90 est alors plus
correct en ne proposant pas ce type sous ce nom), c'est qu'il est
dangereux de faire de l'arithmétique booléenne. Avec un peu de rigueur,
pour un usage courant de contrôle de flux, ce n'est pas un gros
problème. Pour des applications basées sur la logique booléenne, en
automatisme ou en CAO par exemple, il me semble qu'il est mieux de se
faire une classe spécifique. Je l'ai fait, mais elle est certainement
"honteuse" sur le plan de la pureté du C++ ;-)

Quote:
En C++, est-ce le bug, ou pas ? Ou bien faut-il faire:
if((options&PorteAOuverte != false) == (options&PorteBOuverte !=
false)){}


Pour des raisins hystériques, "==" et "!=" sont plus
prioritaires que "&" et "|" Sad
LoL ! J'abuse habituellement des parenthèses, il a suffit que j'écrive

options&PorteAOuverte au lieu de l'habituel options & PorteAOuverte, et
que je copie/colle rapidement pour me faire avoir. Je n'ai jamais
regardé le tableau des priorités, et je dois dire qu'intuitivement, je
me serais de toutes façons fait avoir sur celle-là.
Y a-t-il un risque de brider un compilateur dans ses capacités
d'optimisation en abusant de parenthèses ?

[...]
Quote:
Rien dans la Norme semble permettre une évaluation court-circuit
pour les opérateurs autres que "&&", "||", "?:" (et encore,
l'évaluation court-circuit n'a lieu que tant qu'on n'appelle pas
une version surchargée des opérateurs "&&" ou "||").
Hormis le cas très particulier et bien défini du court-circuit, je ne

vois pas ce qui pourrait empêcher le compilateur d'optimiser à sa guise.
Le seul truc qui me chagrine, c'est l'appel de fonction.
Si j'ai:
int f(int i){//};
.....
a = 0 * f(2);

Si f() est inline, il me semble évident que la question n'a pas de sens.
Elle ne sera pas dévelloppée, sauf si son code l'imposse (volatile,
appel de fonction extern).
Si f() est extern, je pense qu'elle sera appelée dans tous les cas.
Si f() est dans la même unité de compilition que l'appel, sera-t-elle
appelée en fonction de son code ?

Et dans le cas:
a = 0 * (b = f(2));
Toujours appelée, j'imagine.
--
Pierre




Back to top
James Kanze
Guest





PostPosted: Tue Feb 15, 2005 9:24 pm    Post subject: Re: if or ...comment faire Reply with quote

Pierre Maurette wrote:
Quote:
kanze (AT) gabi-soft (DOT) fr a écrit :

Pierre Maurette wrote:

[...]
Au temps pour moi. J'étais une fois de plus dans un contexte C
et non C++ (ou C99), d'où les (0,1) à la place de (false,
true).

Ceci dit, le bool me pose problème même en C++, et sauf erreur
de ma part il masque un danger, pour le débutant ou le
programmeur venant d'un langage dans lequel le booléen est un
vrai type.

Il est naturel, du moins tentant, d'écrire:
if((options&PorteAOuverte) == (options&PorteBOuverte)){}
En C++, est-ce le bug, ou pas ?

Oui. Mais tu ne peux pas le mettre sur le compte de bool, parce
que le bool n'y intervient qu'avec le résultat de ==. Si tu
écris :

if ( ((options & porteAOuverte) != 0)
== ((options & porteBOuverte) != 0) )

il n'y a pas de problème. Dans des cas comme ceci, j'écris
prèsque toujours des petites fonctions d'aide, du genre :

bool
estPorteAOuverte( Options options )
{
return (options & porteAOuverte) != 0 ;
}

Quote:
Ou bien faut-il faire:
if((options&PorteAOuverte != false) == (options&PorteBOuverte !=
false)){}
?

Surtout pas. Il y a deux problèmes :

1. La précédence est mauvaise -- « (options&PorteAOuverte !=
false) » vaut « (options & (PorteAOuverte != false)) », ce
qui vaut « (options & 1), à moins que PorteAOuverte vaut 0,
et

2. même avec des parenthèses en plus, pour faire le comparaison
!=, le compilateur amène les deux côtés au même type. En
l'occurance, le type le plus grand, ce qui n'est
certainement pas bool. Or, si l'expression marche, c'est
uniquement parce que false se convertit en 0 -- changer le
!= false en == true, et l'expression ne marche que si la
masque (PorteAOuverte ou porteBOuverte) vaut 1. Ce qui n'est
prèsque sûrement pas le cas pour les deux.

Je repète donc, la solution propre est de faire des petites
fonctions prédicates, et de s'en servir pour écrire :

if ( estPorteAOuverte( options )
== estPorteBOuverte( options ) )

C'est lisible, ET c'est correct.

Quote:
D'abord, il faut coder au plus près de la logique, or, | est
un opérateur arithmétique et || un opérateur logique.

Sauf que c'est un drôle d'arithmétique. | est un opérateur
bit-à-bit, et || est un opérateur logique.

J'ai toujours considéré les opérateurs bitwise comme des
opérateurs arithmétiques.

Ils le sont, d'un certain point de vue. Seulement, ce n'est pas
ce que la plupart des gens entendent par « arithmétique ».

Quote:
& est à + la même chose que * est à +. C'est à dire que &
appliqué à deux données du même type entier fournit un
résultat de ce même type. Mais peu importe le nom.

Tout à fait. L'importance, c'est justement ce que tu viens de
dire -- les règles de conversion des opérateurs arithmétiques
s'appliquent, et le résultat a le type des opérands une fois
convertis.

En revanche, la précédence est bien celle d'une opération
logique. C'est une erreur ; Richie explique que quand il a
introduit || et &&, il a pensé à corriger la précédence, mais il
y avait déjà des dizaines d'installations du compilateur, et on
n'a pas voulu casser le code existant. (Depuis, je constate
qu'on exagère dans l'autre sens.)

Quote:
En revanche, && entre deux int ne devrait pas exister dans un
langage rigoureux.

Tout à fait d'accord. Mais le C++, et même le C, ont une
histoire.

Quote:
Pour l'admettre, il faut avoir une certaine culture du C
(C++). Ce qui n'est pas une critique, mais la prise en compte
d'une réalité (si C et C++ étaient de mauvais langages, ça se
saurait. S'ils étaient parfaits également).

En fait, tous les langages sont mauvais. Pour une raison ou une
autre. Le C++, c'est seulement un peu moins mauvais que les
autres. :-)

Quote:
[...]

if(exprA || exprB)
n'évaluera pas exprB si exprA est vraie. Je ne pense pas que
ce soit le cas de:
if(exprA | exprB)

Disons plutôt que l'évaluation de G à D et incomplète ne
sont pas garanties par la norme. C'est alors l'optimisation
qui décide.

Le comportement visible du programme doit être comme si les
deux ont été évalué. C'est garanti par la norme. (Donc, si
exprB a des effets de bord, ils auront lieu, quelque soit la
valeur de exprA.) En revanche, l'ordre de l'évaluation n'est
pas spécifié@; si exprA et exprB ont des effets de bord, on
ne sait pas dans quel ordre ils auront lieu.

Pour le court-circuit, pas de problème. C'est même ce que j'ai
essayé d'expliquer. En revanche, j'ai un problème justement
avec:
if(exprA & exprB)
même question avec
if(exprA * exprB)
étant entendu que je préfèrerais écrire:
if((exprA & exprB) != 0)
et
if((exprA * exprB) != 0)

Tout à fait d'accord. Si tu régardes le code que j'écris, tu ne
verras jamais un « if ( a | b ) ».

En général, je n'aime pas les sécrets. Si je ne sais pas que a |
b n'est pas un booléen, je crois qu'il va y avoir des problèmes
dans mon code. Et si je sais qu'il y a une conversion implicite,
et que je connais les règles, pourquoi taire le fait du lecteur.

Quote:
Si (par exemple) exprA est évaluée à 0, dans quels cas suis-je
certain que exprB sera évaluée ? Tout le temps ? Quand elle
contient des appels de fonctions ? Quand elle contient des
variables déclarées volatile ?

Tu sais que le comportement visible du programme serait comme si
exprB a été évalué. Le comportement visible, ce sont les
entrées/sorties et les accès aux variables volatiles. Si le
compilateur ne peut pas prouvé que l'appel de la fonction n'a
pas d'effets de bords qui joue sur les entrées/sorties plus
loins, il faut qu'il génère l'appel.

En revanche, si exprA et exprB ont des effets de bords, l'ordre
dans lequel ils se font n'est pas spécifié.

Quote:
Question subsidiaire: j'imagine que si l'évaluation de exprA
modifie celle de exprB (ou le contraire), j'ai un comportement
indéfini, et donc que je dois éviter (à la différence d'un &&
qui me permet de prévoir). Eviter ou modifier, par exemple:
int tempo;
if((tempo = exprA) != 0)
if(exprB != 0)
Vrai ?

Tout à fait, bien que je ne vois pas le problème dans l'exemple.
Mais quelque chose comme :
if ( (tempo = exprA) | (tempo - 1) )
a un comportement indéfini. (Mais c'est aussi complètement
illisible.)

--
James Kanze home: www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Back to top
James Kanze
Guest





PostPosted: Tue Feb 15, 2005 9:35 pm    Post subject: Re: if or ...comment faire Reply with quote

Pierre Maurette wrote:
Quote:
Falk Tannhäuser a écrit :

[...]

Rien dans la Norme semble permettre une évaluation
court-circuit pour les opérateurs autres que "&&", "||", "?:"
(et encore, l'évaluation court-circuit n'a lieu que tant
qu'on n'appelle pas une version surchargée des opérateurs
"&&" ou "||").

Hormis le cas très particulier et bien défini du
court-circuit, je ne vois pas ce qui pourrait empêcher le
compilateur d'optimiser à sa guise. Le seul truc qui me
chagrine, c'est l'appel de fonction.

Si j'ai:
int f(int i){//};
....
a = 0 * f(2);

Si f() est inline, il me semble évident que la question n'a
pas de sens. Elle ne sera pas dévelloppée, sauf si son code
l'imposse (volatile, appel de fonction extern).

Si f() est extern, je pense qu'elle sera appelée dans tous les
cas.
Si f() est dans la même unité de compilition que l'appel, sera-t-elle
appelée en fonction de son code ?

Où f() se trouve n'entre pas en jeu, ni même s'il est inline ou
non. Le compilateur est obligé de faire en sort que le
comportement visible du programme est le même que s'il a été
appelé. Ensuite, c'est purement et simplement une question des
capacités de l'optimisateur :

-- prèsque tous, sinon tous, sont capable de faire l'analyse
nécessaire si la fonction est inline,

-- certains, comme g++, n'ont pas de problème si la fonction
est dans la même unité de compilation, même si elle n'est
pas inline (mais je crois que g++ ne supprimera l'appel que
s'il décide de générer la fonction inline), et

-- quelques un, mais ils sont rares, sont capables de faire
l'analyse même si la définition de la fonction se trouve
dans une autre unité de compilation.

Quote:
Et dans le cas:
a = 0 * (b = f(2));
Toujours appelée, j'imagine.

A priori.

La norme spécifie le comportement d'une machine abstraite, sans
optimisation. Mais elle donne une liberté absolue à
l'implémentation de faire n'importe quoi, tant que le
comportement visible est le même que celui de la machine
abstraite. Si on a appelé une fonction ou non, ce n'est pas un
comportement visible.

--
James Kanze home: www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Back to top
Pierre Maurette
Guest





PostPosted: Wed Feb 16, 2005 4:37 am    Post subject: Re: if or ...comment faire Reply with quote

James Kanze a écrit :
[...]
Quote:
En revanche, la précédence est bien celle d'une opération
logique. C'est une erreur ; Richie explique que quand il a
introduit || et &&, il a pensé à corriger la précédence, mais il
y avait déjà des dizaines d'installations du compilateur, et on
n'a pas voulu casser le code existant.
Alors qu'en fait il rentrait un peu fatigué du mariage de sa soeur.

Curiosité: tu veux dire que au début il n'existait que | et &, qui
pouvaient servir à faire de la logique moyennant certaines précautions
((1 & 2) == 0, alors que [plus tard] (1 && 2) == 1). Ils avaient
logiquement une priorité haute. Quand Richie introduisit || et &&, il
eut été logique de faire de | et & de simples opérateurs arithmétiques,
et de ramener leur priorité à ce niveau, mais code existant etc. ?
--
Pierre

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.