Bonjour ,
Pouvez-vous m'indiquer si -1 a une valeur comme par exemple 0 vaut false et 1 vaut true svp?
Il me semble l'avoir vu quelque part mais je ne m'en souviens plus .
Version imprimable
Bonjour ,
Pouvez-vous m'indiquer si -1 a une valeur comme par exemple 0 vaut false et 1 vaut true svp?
Il me semble l'avoir vu quelque part mais je ne m'en souviens plus .
Une petite confusion peut être :
- false vaut 0 (et pas l'inverse)
- true vaut toute autre valeur que 0
En fouillant dans les include, tu trouveras certainement des #define du genre
mais je pense que ce n'est pas très intéressant.Code:#define ERREUR -1
En fait, la vraie question c'est "Pourquoi est-ce que tu te poses cette question ?"
Attention: True vaut toute autre valeur que 0, mais il me semble que !0 (non logique(zéro)) est garanti retourner 1 en C.
Ce n'est pas le cas de tous les langages: En Visual Basic, un test vrai retourne -1.
Pour appuyer ce que dit Médinoc:
Cordialement.Citation:
6.5.3.3 Unary arithmetic operators
Constraints
1 The operand of the unary + or - operator shall have arithmetic type; of the ~ operator,
integer type; of the ! operator,scalar type.
Semantics
...
5 The result of the logical negation operator ! is 0 if the value of its operand compares
unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int.
The expression !E is equivalent to (0==E).
Merci nicolas.sitbon de cette précision :ccool:, mais par curiosité, c'est quoi ta spec du langage C ? Peut on la consulter facilement en ligne ?
Le lien vers la norme peut être trouvé dans ce message d'information du forum.
Attention matthew974 !
En C, comme te l'ont indiqué nos petits camarades, on se sert des int pour coder une information booléenne.
Mais la valeur TRUE n'est pas spécifiée.
Personnelement, je recommande 2 defines :
MAIS attention, il ne faut JAMAIS tester TRUE directement !Code:
1
2 #define TRUE (1==1) #define FALSE (1==0)
peut conduire à une erreur !Code:if (ma_fonction( 5 ) == TRUE) printf("vrai pour 5") ;
Si ma_fonction( 5 ) renvoie 123, ce teste échoue alors que 123 est interprété comme la valeur booléenne vraie par le C (puisque non nulle).
Cette versionmarche toujours...Code:if (ma_fonction( 5 )) printf("vrai pour 5") ;
En revanche, tu peux faire des return TRUE ; ou des return FALSE ;
Quelle horreur !!!!
Si ta fonction est censée retourner un entier, il faut tester par rapport à la valeur définie dans la doc..
Il est bien évident que TRUE n'est pas un entier au sens du retour de la fonction..
Donc ce que tu dis est absurde, et c'est même strictement le contraire des bonnes pratiques !!!
Il faut AU CONTRAIRE tester par rapport à la valeur spécifiée..
- Si c'est un pointeur, il faut tester par rapport à NULL
- Si c'est un booléen (??? Faut voir les définitions, puisque le type n'existe pas en C) il faut tester par rapport soit à (True ou False) soit, implicitmenet
- Si c'est un entier, il faut tester par rapport à la valeur référencée dans la doc
- Si c'est un réel, il faut tester par rapport à la valeur spécifiée dans la doc
- Si c'est une structure, il faut tester par rapport à NULL (FILE * par exemple) ou par rapport à la valeur définie dans la doc
Les tests implicites conduisent immanquablement à des erreurs (par exemple des fonctions comme strcmp donnent 0 pour VRAI), et de plus conduisent à du code obfusqué..
Dans ton exemple, si on écrit :
bien sûr que le test échoue.. Ce n'est pas parce que TRUE est mauvais, c'est parce que tu n'as pas lu la définiton de la fonction ma_fonction.... et que justement tu appliques bêtement le fait que le résultat du test est un booléen... PAS LE TEST EN LUI MEME !!!Code:if (ma_fonction( 5 ) == TRUE) printf("vrai pour 5") ;
Quelle horreur !!!
Tu crées des outils dont l'utilisation entraine une erreur de prog et t'impose ensuite des contraintes spéciales !!!
Contente-toi de respecter la norme => 0 = faux et "pas 0" = vrai
Ensuite, ben tu te contentes de tests classiques
if (maFonction() != 0) => vrai
if (maFonction() == 0) => faux
Si ce que la fonction retourne est explicitement un booléen d'après la doc (avec ou sans typedef), alors le if() "nu" est bien ce qu'il faut faire.
Par contre, utiliser un if() "nu" sur toute autre valeur (pointeur, strcmp(), etc.) ne cause que confusion et difficulté de lecture.
Pour information, le type bool existe en C99 (donc ça va bientôt faire 10 ans (ainsi que true et false). Pas la peine de réinventer un truc défini dans la norme (modulo les implémentations qui supportent pas ce genre de feature basique de C99).
Pour appuyer ce que dit zul:
Cordialement.Citation:
6.2.5 Types
...
2 An object declared as type _Bool is large enough to store the values 0 and 1.
...
...
6.3.1.2 Boolean type
1 When anyscalar value is converted to _Bool,the result is 0 if the value compares equal
to 0; otherwise, the result is 1.
...
...
7.16 Boolean type and values <stdbool.h>
1 The header <stdbool.h> defines four macros.
2 The macro
bool
expands to _Bool.
3 The remaining three macros are suitable for use in #if preprocessing directives. They
are
true
which expands to the integer constant 1,
false
which expands to the integer constant 0, and
__bool_true_false_are_defined
which expands to the integer constant 1.
4 Notwithstanding the provisions of 7.1.3, a program may undefine and perhaps then
redefine the macros bool, true,and false.
Ok, ok, ne vous énervez pas les gars !
Je suis tout à fait d'accord sur ce point :
Si on a dans un header partagé quelque chose comme ça :Puis ailleurs, un prototype de fonction comme ça :Code:
1
2
3
4 typedef int BOOL ; #define FALSE (1==0) #define TRUE (1==1)
Alors bien sûr, il est absurde de supposer que la fonction peut renvoyer 123.Code:
1
2
3
4
5
6 /** Bla bla... @param Bla bla... @return TRUE si..., FALSE sinon */ BOOL ma_fonction ( int mon_param ) ;
Ca peut d’ailleurs faire l’objet de vérifications de post conditions.
--MAIS--
J’en ai vu pas mal, des fonctions de librairies tiers avec des spec du genre "...return non zero value elsewere..." et testées avec des "== TRUE" !
Si la fonction en question renvoie des valeurs très variées, on s'aperçoit vite du bug et on le corrige.
Mais j'ai déjà perdu du temps avec du code hérité sur ce genre de problème lorsque la fonction renvoie "presque toujours" 1 pour signifier vrai. Du coup on tombe sur des bugs aléatoires et irreproductibles, les pires de tous...
Le problème c'est que dans la vraie vie on n'est pas toujours maître du code sur lequel on travaille et les bonnes pratiques sont loin d'être généralisées.
Bref, tout ça pour dire que (si on n'a pas la chance de travailler avec C99 et son bool natif) il vaut mieux tester les booléens avec un if nu plutôt qu'avec des valeurs explicites dont l'usage n'est pas respecté par tous.
L'existence de defines BOOL, TRUE et FALSE peut faire croire au novice qu'il existe une vraie gestion des booléens...
La question de matthew974 (qui est, je le rappelle, le point de départ) laisse supposer qu'il est lui même tombé sur une de ces spec floues et que la gestion des booléens par C90 n'est pas encore claire pour lui.
Ce qui est exactement ce que tu conseillais.... :aie:
Raison de plus pour mettre en oeuvre les "bonnes pratiques", et non pas des bidouillages qui ne peuvent qu'amener des désagréments (forts) ultérieurs..
Tout ça pour dire qu'en dehors de C99 IL N'Y A PAS DE BOOL EN C ..
Et donc que tout test doit être effectué avec ce qui est spécifié dans la doc....
Donc ne t'enfonce pas plus...
Encore une fois c'est le résultat du test qui peut être testé "nu"...
Le test lui-même NON ...
PS : je n'ai jamais rencontré de biblothèques où ce genre de trucs était répandu.. Si c'est ce que tu utilises, change vite de fournisseurs...
Pas d'accord. Si une fonction retourne une valeur documentée comme "doit être interprétée comme un booléan", c'est le if nu qui convient.
Ça a longtemps été le cas sous Visual:Citation:
PS : je n'ai jamais rencontré de biblothèques où ce genre de trucs était répandu.. Si c'est ce que tu utilises, change vite de fournisseurs...
CDaoRecordset::IsEOF retourne un BOOL, mais ne garantit pas "TRUE" --> if nu.
PS: Bien sûr, on ne peut rien faire pour les cas extrêmes de stupidité où "TRUE" est nul...
Combien de fois as-tu vu ça ??
Et non pas "retourne True ou False" ??
C'est vrai que je n'ai guère (à part avec Delphi) programmé sur M$...
Encore une fois, vive M$ et ses particularismes..
Mais ce n'est pas le comportement standard, et donc encore une fois pourquoi violer la règle pour s'adapter à une exception ??
Je ne connais pas de fonction standard retournant une valeur documentée comme booléenne, donc le problème ne se pose pas: En standard, à moins de se créer un type booléen (ou utiliser celui de C99), on n'utilise jamais de if nu.
J'admets qu'il y a une part de subjectivité, mais mon raisonnement l'étend à ma définition même de "type booléen" : Pour moi, c'est un type qu'on peut tester avec un if nu (edit: et qui en a la sémantique). Si on ne peut pas (comme l'enum avec FileNotFound), je refuse de reconnaître le type en question comme un type booléen.
Edit: Cette définition est compatible avec .Net et Java.
Nous sommes d'accord :D
Et donc, je pense qu'il est de notre devoir, dans un forum intitulé "Débuter", de lutter fortement contre le fait d'utiliser des "if" nus..
Et l'argument et le texte de sopsag est à corriger vivement, pour ne pas (y compris pour lui) induire de mauvais comportements..
PS :
Tout le code de X11 (ou freeX86 pour ceux utilisant Linux) est en C avec un type booléen.. Depuis 1984...
Etant donné que je suis une des rares personnes du forum à utiliser C99 tous les jours (au boulot en l'occurrence), je précise que je suis moi même cette convention, à savoir qu'un if nu, indique forcément une expression de type bool (_Bool) et rien d'autre.
Cordialement.