OVH Cloud OVH Cloud

bool

64 réponses
Avatar
Fabien LE LEZ
Bonjour,

Un peu HS ici, mais je ne peux m'empêcher de vous faire profiter d'une
perle de l'API Windows :

typedef int BOOL;
#define FALSE 0
#define TRUE 1
C'est limite, mais prévu à l'origine pour les compilateurs sans type
bool.

BOOL GetMessage (/*je vous fais grâce des paramètres*/);

Pas de problème non plus... sauf cette remarque :

Note that the function return value can be TRUE, FALSE, or -1.

Les profs de C++ pourraient se servir de cet exemple pour illustrer
les magnifiques méthodes d'obfuscation utilisées dans l'industrie ;-)


--
;-)

10 réponses

Avatar
DINH Viêt Hoà

Oulà, je n'ai rien compris. C'est assez obfusqué (un nouveau mot tous
les jours) ton explication.
Effectivement, pas clair (c'est HS). En MASM :

.WHILE TRUE
invoke GetMessage, ADDR msg, NULL, 0, 0
.BREAK .IF (!eax)
inc eax
jz TraiterErreur
[ou .CONTINUE .IF(!eax)]
etc.


effectivement, c'est encore plus clair (...)

ce serait plutôt :

ptr = malloc(...);
if (ptr == NULL) {
^^^^
...
}

Je continue donc à l'utiliser, quand mon compilateur le reconnait sans

include particulier, c'est à dire tout le temps. Mais quand je poste ici, je
reviens au 0, pour éviter les remarques. C'est donc raté.


hum ... je pense qu'utiliser 0 est pire que tout.

quand à la valeur de retour de l'opérateur new, me semble-t-il qu'on n'a
pas besoin de la tester, soit une a une exception, soit il réussit.
L'opérateur new peut être utilisé en version nothrow. Il ne lance pas alors

d'exception, mais comme malloc(), renvoie le pointeur nul en cas d'échec.
D'où "(ou new() dans certaines conditions)".


est-ce spécifié par la norme C++ ce "nothrow" ?

Reste qu'avec ton exemple, je ne vois pas le rapport non plus.
Quand les booléens ne suffisent plus à communiquer un code de retour, en
général, on essaie d'utiliser un entier (ce qui est généralement utilisé
en C) ou autre (ou alors une exception si c'est en C++).
Je m'impose des règles (de style) qui différencient absolument entiers et

booléens. Pas d'arihmétique entière sur ces derniers par exemple, etc.
pour les tests, c'est if(varInt == 0) et if(!varBool), jamais le contraire.


il suffit d'utiliser les "enum" sur lesquels on n'est pas censé avoir
d'arithmétique.

Sur ce dernier point, je m'accorde une liberté avec les pointeurs que nous
venons d'évoquer, en prenant en compte l'aqspect booléen de leur
comportement


heu ... si tu pars comment ça, tous les types scalaires en C et C++ ont
"un comportement booléen" ...
Je préfère éviter de "profiter" de ce comportement afin d'éviter les
erreurs. Je trouve les quelques extraits de votre code pas très clairs,
obfusqué diront-nous.

Mais c'est peut-être une habitude donnée par MSDN ou developpez.com, qui
sait ?

--
DINH V. Hoa,

etPan! - newsreader, mail user agent -- http://libetpan.sf.net/etpan


Avatar
DINH Viêt Hoà

Bah oui, mais là il s'agit d'un booléen à trois valeurs ~_~
Il aurait quand même été plus heureux de renvoyer un int ou quelque
chose du même style...
C'est un TRIBOOL !



tiens, un corps à ajouter à la théorie des ensembles ?

Dans la dernière version du MSDN que j'ai, il y a un récapitulatif "Windows
Data Types". Le BOOL est décrit "Boolean variable (should be TRUE or
FALSE)". Et aussi un type BOOLEAN avec strictement la même définition.
Un truc maison genre WPARAM ou LRESULT, avec une enum qui va bien peut-être,
aurait sans doute convenu.
Tiens, le LRESULT aussi est assez rigolo : sur certaines fonctions, "renvoie
0 si la fonction a réussi" ;-)


Il suffit de bien spécifier le comportement.

Sous unix, beaucoup de fonctions renvoient 0 en cas de réussite, et un
nombre différent de zéro en cas d'échec, ce nombre donne le code
d'erreur. 0 était défini comme le code d'erreur "pas d'erreur", on a à
peu près une cohérence.

Enfin on peut également faire la réflexion inverse.
Soit une fonction qui peut échouer sur différents types d'erreurs et
elle peut également réussir, on retourne un code d'erreur. Si le code
d'erreur est un entier et qu'il y en a plusieurs, on aura au moins un
code d'erreur différent de zéro. Ce qui pousse pas mal à les choisir
tous différents de zéro et à choisir une valeur arbitraire pour le code
de réussite, et pourquoi pas zéro ?

--
DINH V. Hoa,

etPan! - newsreader, mail user agent -- http://libetpan.sf.net/etpan


Avatar
kanze
Gabriel Dos Reis wrote in message
news:...

"Pierre Maurette" <mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> writes:

| Je vois là un certain rapport avec le void* retourné par exemple par
| malloc() (ou new() dans certaines conditions) : pour moi, c'est un
| semi booléen, et donc je vais écrire if((ptr=malloc())) ou
| if(!(ptr=malloc())),

à chaque fois je vois ça, j'ai envie de jeter le programme par la
fenêtre -- C idiomatique ou non.


Tiens, on est d'accord pour une fois.

| et ne pas me forcer à if((ptr=malloc())!=0) ou
| if((ptr=malloc())==0), mais c'est personnel.


Là aussi. Qu'est-ce qu'il a contre le simple :

ptr = malloc( n ) ;
if ( ptr != NULL ) ...

(On peut discuter sur le NULL. Je le préfère, mais je comprends aussi
les arguments contre. Pour la reste...)

En C++, je comprends un peu l'argument pour quelque chose comme :

if ( void* ptr = malloc( n ) ) ...

Le pointeur ptr n'est pas visible ailleurs qu'où il a une valeur
utilisable.

Je comprends donc l'argument, mais je ne suis pas convaincu. Je n'aime
toujours pas.

Le principe de base, c'est qu'une instruction ne fait qu'une seule
chose. Quand je vois un if ou un while comme premier token dans la
ligne, je sais que j'ai affaire à un contrôle de flux, et donc que
l'état du programme ne est pas modifié.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
kanze
Fabien LE LEZ wrote in message
news:...
On Thu, 4 Dec 2003 16:29:20 +0100, "Pierre Maurette"
<mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wrote:

Le choix du nom BOOL ne semble effectivement pas très heureux,
d'autant plus que Microsoft ne se prive pas par ailleurs pour créer
des noms de types bien spécifiques. Pour atténuer un peu la
critique, les fonctions API sont du C utilisables en C++, et donc le
type bool n'existait pas :


Bah oui, mais là il s'agit d'un booléen à trois valeurs ~_~ Il aurait
quand même été plus heureux de renvoyer un int ou quelque chose du
même style...


Surtout qu'on peut bien imaginer un jour où quelqu'un met le code à
jour, en changeant le « typedef int BOOL » en « typedef bool BOOL ».

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
kanze
Gabriel Dos Reis wrote in message
news:...
"Thomas Abbé" writes:

| ou est le probleme ? on distingue 3 cas !

Un machin qui a trois éléments n'est pas un type booléen.


Mais qui te dit que BOOL signifie un type booléen. C'est sans doute un
acronyme pour Binary Or Other Logic, ou quelque chose du genre. :-)

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
kanze
Richard Delorme wrote in message
news:<3fcfaa94$0$6972$...

On Thu, 04 Dec 2003 10:20:03 +0100, Richard Delorme
wrote:

du verbe offusquer, qui veut dire « cacher à la vue, empêcher de
voir »,


C'est marrant, mon Larousse une définition très différente de ce
verbe (celle que je connaissais, en fait) : choquer, déplaire à.


C'est un sens figuré d'offusquer, le sens premier est celui que je
donne.


En fait, je trouve que le sens secondaire ajoute à la valeur du mot
ici. D'un certain côté, les deux sens valent.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16



Avatar
Benoit Rousseau
Richard Delorme wrote:


On Thu, 04 Dec 2003 10:20:03 +0100, Richard Delorme
wrote:


du verbe
offusquer, qui veut dire « cacher à la vue, empêcher de voir »,


C'est marrant, mon Larousse une définition très différente de ce verbe
(celle que je connaissais, en fait) : choquer, déplaire à.



C'est un sens figuré d'offusquer, le sens premier est celui que je donne.
Pour une définition complète, tu peux consulter le TLFi :
http://atilf.atilf.fr/tlf.htm


Mais ta définition est "vieillie" (sans vouloir t'offusquer :-)



--
--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/



Avatar
Pierre Maurette
a écrit
[...]
Là aussi. Qu'est-ce qu'il a contre le simple :

ptr = malloc( n ) ;
if ( ptr != NULL ) ...
Rien, c'est ce que j'utilise le plus souvent.

J'ai déjà répondu pour la ligne unique à la place des deux lignes et pour le
NULL.

[...]
Le principe de base, c'est qu'une instruction ne fait qu'une seule
chose. Quand je vois un if ou un while comme premier token dans la
ligne, je sais que j'ai affaire à un contrôle de flux, et donc que
l'état du programme ne est pas modifié.
Je pense également que c'est un bon principe.

De plus, le traçage (debogueur) en est plus efficace.
J'apprécie l'ouverture d'esprit de vos réponses, dans lesquelles vous
admettez qu'il y a des habitudes qui sont admissibles. Ces habitudes de
style puisent leur source dans le vécu du programmeur. Le problème, c'est
que le rédacteur et le lecteur n'ont pas nécessairement le même vécu.
un exemple, our la forme correcte :
a = b;
if(a == c)...
La forme :
if((a = b) == c)...
me "parle", c'est à dire que je la lis sans effort et sans risque d'erreur.
En revanche, je refuse l'écriture :
if(a = b == c) ...
qui est pourtant non ambigüe et qui se rencontre.

Donc, no problemo, dans le cas du if(), on laisse deux lignes.
Maintenant :
while((A = f()) != ERROR)
{
// Code utilisant A
}
J'aurais du mal à m'en passer. Les autres formes sont pour moi plus confuses
à la lecture.
Ou alors, peut-être préférez-vous :
while(A = f(), A != ERROR)
{
// Code utilisant A
}
Ça semble effectivement efficace.

Pierre

Avatar
Pierre Maurette
"DINH Viêt Hoà" a écrit
[...]
est-ce spécifié par la norme C++ ce "nothrow" ?
ISO/IEC 14882:1998(E), §18.4.1.1


Pierre

Avatar
DINH Viêt Hoà

Je pense également que c'est un bon principe.
De plus, le traçage (debogueur) en est plus efficace.
J'apprécie l'ouverture d'esprit de vos réponses, dans lesquelles vous
admettez qu'il y a des habitudes qui sont admissibles. Ces habitudes de
style puisent leur source dans le vécu du programmeur. Le problème, c'est
que le rédacteur et le lecteur n'ont pas nécessairement le même vécu.
un exemple, our la forme correcte :

a = b;
if(a == c)...
La forme :
if((a = b) == c)...
me "parle", c'est à dire que je la lis sans effort et sans risque d'erreur.
En revanche, je refuse l'écriture :
if(a = b == c) ...
qui est pourtant non ambigüe et qui se rencontre.


votre code est-il aussi clair et lisible que vos réponses ? ;)
Cela manque un peu d'espacement.

Enfin continuons sur le sujet qui nous intéresse :

je préfère :

if (a == c)

à :

if(a == c)

Donc, no problemo, dans le cas du if(), on laisse deux lignes.
Maintenant :

while((A = f()) != ERROR)
{
// Code utilisant A
}


j'utilise de temps en temps cette forme, notamment avec fgets() mais
j'essaie de l'éviter le plus souvent.

J'aurais du mal à m'en passer. Les autres formes sont pour moi plus confuses
à la lecture.

Ou alors, peut-être préférez-vous :

while(A = f(), A != ERROR)
{
// Code utilisant A
}
Ça semble effectivement efficace.


Je préfère :

while (1) {

A = f();
if (A != NO_ERROR)
break;

// ...
}

--
DINH V. Hoa,

etPan! - newsreader, mail user agent -- http://libetpan.sf.net/etpan