IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Signification d'un double point d'interrogation


Sujet :

C

  1. #1
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 700
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 700
    Points : 15 043
    Points
    15 043
    Par défaut Signification d'un double point d'interrogation
    Bonjour,

    à ce jour, en C comme dans un tas d'autres langages, je connaissais ! que je traduis par "inverse ce qui suit".

    Mais aujourd'hui, dans le code source de pulseaudio12.2, je rencontre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                    conf->system_instance = !!b;
    Sachant que conf->system_instance est un bool et b un int, je me (vous !) demande tout simplement pourquoi ne pas avoir écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    conf->system_instance = b;
    Merci de vos (comme d'habitude ) lumineuses explications, et bon 14 juillet !
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 627
    Points : 10 551
    Points
    10 551
    Par défaut
    J'ai regardé sur Internet, et la réponse est dans la question

    En C, toute valeur différente de 0 est true. Avec la double négation logique, on uniformise en réduisant aux valeurs 1 ou 0.
    • 0, false - !!0 vaut 0
    • n’importe quelle autre valeur, true - !!X vaut 1


    Il y a surtout plusieurs manières de faire ... + ou - portable, mais effectivement 1 test ternaire me semble plus propre ((X != 0)? 1: 0).

  3. #3
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 700
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 700
    Points : 15 043
    Points
    15 043
    Par défaut
    Pas trouvé sur le web (faut dire aussi que rechercher langage C explication "!!" ne m'a pas remonté des merveilles, fallait pas rêver).

    Merci pour ta réponse, cependant tu ne réponds pas à ma question : pourquoi ne pas avoir utilisé tout simplement conf->system_instance = b; puisque si b vaut 0 le boolean sera false, sinon il sera true.
    Et c'est exactement ce que tu écris.

    Je ne vois pas ce que
    Citation Envoyé par foetus Voir le message
    on uniformise en réduisant aux valeurs 1 ou 0.
    apporte.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 627
    Points : 10 551
    Points
    10 551
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Pas trouvé sur le web (faut dire aussi que rechercher langage C explication "!!" ne m'a pas remonté des merveilles, fallait pas rêver).
    Il faut chercher "C double not logical"


    Citation Envoyé par Jipété Voir le message
    pourquoi ne pas avoir utilisé tout simplement conf->system_instance = b; puisque si b vaut 0 le boolean sera false, sinon il sera true.
    pour cela il faut lire le code, et voir comment cette variable conf->system_instance est utilisée.
    Mais on peut penser que conf veut dire configuration, et que dans 1 fichier de configuration ou 1 de base données, c'est plus facile d'avoir 2 valeurs 0 et 1 (les tests, le parsage des valeurs, l'écriture, ...) que 58446591 pour true

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    C'est une vieille syntaxe qui rapporte !b sur [0,1] puis prend l'inverse. Qui permet d'avoir 1 si b != 0, 0 sinon.
    Une syntaxe récente sera juste conf->system_instance = b != 0;
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 627
    Points : 10 551
    Points
    10 551
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Une syntaxe récente sera juste conf->system_instance = b != 0;
    Non la + récente est 1 cast conf->system_instance = (_Bool) b;.

    Édit : Et même ici le cast ne sert à rien parce qu'on travaille en C et il faut que la variable conf->system_instance soit de type _Bool.
    Donc la solution la + récente mais effectivement, il faut utiliser le nouveau type C99 dans son code ... ce qui ne semble pas être le cas

  7. #7
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 700
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 700
    Points : 15 043
    Points
    15 043
    Par défaut
    Citation Envoyé par foetus Voir le message
    pour cela il faut lire le code, et voir comment cette variable conf->system_instance est utilisée.:
    Y aura pas des millions de possibilités, hein :
    Citation Envoyé par Jipété Voir le message
    Sachant que conf->system_instance est un bool
    (conf c'est la structure des options de configuration, oui)


    Citation Envoyé par foetus Voir le message
    Il faut chercher "C double not logical"
    Fallait en avoir l'idée ! Bien joué !
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 631
    Points : 30 865
    Points
    30 865
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Jipété Voir le message
    Y aura pas des millions de possibilités, hein :
    Hé non. Et j'ai beau chercher, je ne vois pas non plus l'avantage à forcer "b" à être 1 plutôt que 572542. Même la brillante () suggestion de foetus à propos des bdd ne me convainc pas (l'insertion d'un int dans un bool provoquera un cast implicite dans le champ de la bdd) ; et dans le code C lui-même, partout où b sera utilisé comme un booléen, alors sa valeur réelle n'a pas d'importance (sauf si évidemment on vient tester explicitement if (conf->system_instance == 1) mais je ne pense pas qu'un professionnel C fasse cette monumentale bêtise).
    Toutefois admettons que pour une obscure raison cela soit nécessaire, alors comme foetus j'aurais préféré le ternaire bien détaillé => conf->system_instance=b ?1 :0. Là avec son !!b je pense que l'auteur de pulseaudio12 a voulu écrire un truc à la "one again" mais qui ne séduit en fait personne.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 826
    Points : 218 287
    Points
    218 287
    Billets dans le blog
    117
    Par défaut
    Bonjour,

    Je pense que cela devient nécessaire lorsque vous ne savez pas exactement si le type pour représenter un booléen sera équivalent au int. En effet, dans un logiciel multi-plateforme, dont les plateformes cibles sont très variées, le type pour les booléens peut être un int, comme il peut être totalement différent sur une autre plateforme.
    La solution par le cast explicite de foetus est équivalente, mais pas nécessairement jolie (car le cast, peut être considéré comme le mal ?).

    Ensuite, j'ai testé sur godbolt.org, la sortie ASM. Mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef int bool;
    int myConf = 42;
    bool b = 4242;
     
    int foo() {
        myConf = !!b;
        //myConf = (bool) b;
    }
    La version avec le cast, c'est deux mov :
    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            mov     eax, DWORD PTR b[rip]
            mov     DWORD PTR myConf[rip], eax

    La version avec la double négation :
    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
            mov     eax, DWORD PTR b[rip]
            test    eax, eax
            setne   al
            movzx   eax, al
            mov     DWORD PTR myConf[rip], eax
            nop

    Donc, mouais ...
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  10. #10
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 562
    Points : 7 628
    Points
    7 628
    Par défaut
    @LittleWhite, je ne comprends pas le lien entre ce que tu écris et l'exemple que tu donnes.
    Ton exemple montre que si le type bool n'est pas le _Bool du langage C, le fait de faire un cast ne donne pas le résultat attendu, et donc que l'utilisation du double '!' est plus sure.
    Il a totale équivalence, et ces trois expressions aurons le même code assembleur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    _Bool x1 = (b != 0);
    _Bool x2 = !!b;
    _Bool x3 = (_Bool)b;
    Si par contre on a un type bool qui n'a donc pas la conversion implicite : tout nombre converti en bool devient 1 s'il est non nul et 0 sinon. Et dans cas, la troisième ligne est à éviter. Personnellement j'utilise la première forme, mais j'aime bien la seconde.

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 627
    Points : 10 551
    Points
    10 551
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Y aura pas des millions de possibilités
    Si il y a 1 différence entre la notion booléenne mathématique (2 valeurs, vrai ou faux) et la notion C (parce qu'il n'y a pas de booléen, sauf à partir du C99 avec le type _Bool)

    Donc il y a 1 dichotomie entre les données en mémoire et celles externes dans 1 fichier ou 1 base de données, par exemple.
    Et pour des données externes, il faut faire en sorte que tes valeurs ont la notion que tout le monde attend (et non pas 1 valeur informatique de geek )


    Citation Envoyé par dalfab Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    _Bool x1 = (b != 0);
    _Bool x2 = !!b;
    _Bool x3 = (_Bool)b;
    Ton code montre que le cast n'est pas nécessaire ... parce qu'on est en C
    Si j'ai mis le cast c'est parce qu'on ne connait pas les types de conf->system_instance et de b (<- en réalité, mon commentaire est mauvais parce qu'il faut utiliser ce type dans son code)


    Si par contre on a un type bool qui n'a donc pas la conversion implicite
    En C99, le type booléen existe _Bool Et dans l'entête stdbool.h tu as des alias : bool, false et true.
    Je ne travaille pas avec mais je m'attends qu'il fasse les conversions implicite vers les valeurs 0 et 1.


    tout nombre converti en bool devient 1 s'il est non nul et 0 sinon. Et dans cas, la troisième ligne est à éviter.
    Explique pourquoi C'est ce qu'on recherche, non ?

  12. #12
    CGi
    CGi est déconnecté
    Expert éminent
    Avatar de CGi
    Inscrit en
    Mars 2002
    Messages
    1 026
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 1 026
    Points : 8 311
    Points
    8 311
    Par défaut
    Ce qui fausse le résultat de Littlewhite, c'est le :
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  13. #13
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 700
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 700
    Points : 15 043
    Points
    15 043
    Par défaut
    Citation Envoyé par foetus Voir le message
    Si j'ai mis le cast c'est parce qu'on ne connait pas les types de conf->system_instance et de b
    Mais si ! Et depuis le début, et c'est dans le code :

    Citation Envoyé par Jipété Voir le message
    Sachant que conf->system_instance est un bool et b un int,
    Plus précisément : system_instance est un membre (parmi plein d'autres) de type booléen niché au cœur de la structure conf.

    Vous allez me perdre, là, (smiley bateau_qui_coule -- on ne l'a pas, celui-là, )
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  14. #14
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 631
    Points : 30 865
    Points
    30 865
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Vous allez me perdre, là,
    C'est parce qu'on est en train de discuter du sexe des anges. Tout le monde a son avis et les avis de chacun sont tous valables à cause de la permissivité du C concernant le booléen.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 700
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 700
    Points : 15 043
    Points
    15 043
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    C'est parce qu'on est en train de discuter du sexe des anges.


    M'en vais te leur soulever la jupe, moi, on va y voir plus clair :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #include <stdio.h>
     
    int main(int argc, char **argv)
    {
      _Bool systeminstance;
      int b;
     
      b = 0;
      systeminstance = b;
      printf("%d\n", systeminstance);
     
      b = 1;
      systeminstance = b;
      printf("%d\n", systeminstance);
     
      b = 9;
      systeminstance = b;
      printf("%d\n", systeminstance);
     
      systeminstance = !b;
      printf("%d\n", systeminstance);
     
      systeminstance = !!b;
      printf("%d\n", systeminstance);
     
    	return 0;
    }
    et on s'en doute, la console nous dit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    # ./test 
    0
    1
    1
    0
    1
    #
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Résultat et explication d'une instruction
    Par mr.bigka dans le forum Débuter
    Réponses: 2
    Dernier message: 01/12/2013, 19h26
  2. Explication d'une instruction
    Par DANIA511 dans le forum OpenCV
    Réponses: 2
    Dernier message: 03/05/2012, 13h32
  3. [Débutant] Explications sur quelques instructions en Assembleur
    Par voodka2007 dans le forum x86 32-bits / 64-bits
    Réponses: 4
    Dernier message: 01/01/2009, 22h47
  4. Explication d'une instruction de test
    Par ToTo13 dans le forum C
    Réponses: 8
    Dernier message: 07/02/2007, 18h02
  5. Explication sur une instruction...
    Par snoop dans le forum C++
    Réponses: 5
    Dernier message: 03/05/2006, 23h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo