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 :

Probleme avec un "right shift" [Bug report]


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 8
    Points : 2
    Points
    2
    Par défaut Probleme avec un "right shift"
    Salut à tous,

    Je suis nouveau sur le forum mais pas dans le langage C
    Ceux pour qui la notion de "integer promotion" ne veut rien dire peuvent s'arrêter de lire ici

    J'ai un soucis avec le code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       volatile unsigned char v = 128;
       v = v >> 7;
       printf ("volatile unsigned char: %d\n", v);
    qui affiche 255 au lieu de 1 lorsqu'il est compilé avec ICC sous linux.

    J'ai la solution pour éviter le problème: il suffit de caster v et d'écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       v = ((unsigned int) v) >> 7;
    Cependant, je ne comprends vraiment pas comment on peut arriver à 255, sauf si le compilo ICC ne sait pas faire de promotion d'entier.

    Normalement, la bonne marche (conforme aux normes en vigueur) veut que:
    - soit le compilo fait du "unsigned preserving", auquel cas v est converti en "unsigned int" avant décalage et tout se passe bien,
    - soit le compilo fait du "value preserving", auquel cas il devrait convertir v en "int" avec la valeur positive 128 (et non 0xffffff80 comme il semble faire, c'est-à-dire comme si v était négatif parce qu'il a son bit de poids fort à 1...).

    Je ne comprends donc pas ce qu'il peut bien se passer.

    Des idées ?

  2. #2
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Je ne sais pas sous quel processeur ton compiles ton code... Mais vu que j'ai le compilateur icc et gcc sur différentes machines, je l'ai testé:

    Sur un Athlon XP Dual Core: Effectivement il y a ce problème. icc utilise l'instruction assembleur sarb tandis que gcc utilise shrb. Gcc n'a pas ce problème shrb faisant ce que tu veux...

    Sur un Itanium, les deux compilateurs rendent bien 1.

    C'est peut-être un problème d'option...

    Espérant que cela te donnera une piste,
    Jc

  3. #3
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 727
    Points
    1 727
    Par défaut
    Et en faisant l'affectation de v apres sa declaration?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    volatile unsigned char v;
    v = 128;
    v = v >> 7;
    Enfin, ça m'etonnerait que ça change kekchose

  4. #4
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par Gruik
    Et en faisant l'affectation de v apres sa declaration?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    volatile unsigned char v;
    v = 128;
    v = v >> 7;
    Enfin, ça m'etonnerait que ça change kekchose
    Non, cela ne changerait rien pour le compilateur et donc l'exécution...

  5. #5
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut Re: Probleme avec un "right shift"
    Citation Envoyé par divad38
    Je suis nouveau sur le forum mais pas dans le langage C
    Ceux pour qui la notion de "promotion d'entier" ne veut rien dire peut s'arrêter de lire ici
    Effectivement ça ne veut rien dire. char peut être promu, short, aussi, mais 'entier', je ne connais pas.

    Donc, je m'arrête ... Can't resist...

    Ton code est incomplet. Il ne compile pas.
    Manque <stdio.h>
    Je ne suis pas sûr de la promotion d'un unsigned char en int. Dans le doute, je caste et je mets les formatteurs qui vont bien...

    Ceci est complet et est correct :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include <stdio.h>
     
    int main(void)
    {
       volatile unsigned char v = 0x80;
       v >>= 7;
       printf ("volatile unsigned char: %u\n", (unsigned) v);
       return 0;
    }
    Sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    volatile unsigned char: 1
    Pas de Wi-Fi à la maison : CPL

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 8
    Points : 2
    Points
    2
    Par défaut Re: Probleme avec un "right shift"
    Citation Envoyé par Emmanuel Delahaye
    Citation Envoyé par divad38
    Je suis nouveau sur le forum mais pas dans le langage C
    Ceux pour qui la notion de "promotion d'entier" ne veut rien dire peut s'arrêter de lire ici
    Effectivement ça ne veut rien dire. char peut être promu, short, aussi, mais 'entier', je ne connais pas.

    Donc, je m'arrête.
    In english we say "integer promotion".
    If you don't care, we can continue in english, never mind.

    Thanks for your precious help.

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Gruik
    Et en faisant l'affectation de v apres sa declaration?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    volatile unsigned char v;
    v = 128;
    v = v >> 7;
    Enfin, ça m'etonnerait que ça change kekchose
    Non, ça ne change rien

    Par contre, dans les cas suivants ça affiche 1:
    1) v >>= 7;
    2) en déclarant "v" sans le mot-clé "volatile"
    3) en compilant avec gcc sur iX86, gcc ou cc sur architecture Sparc.

    Etrange...

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par fearyourself
    Je ne sais pas sous quel processeur ton compiles ton code... Mais vu que j'ai le compilateur icc et gcc sur différentes machines, je l'ai testé:

    Sur un Athlon XP Dual Core: Effectivement il y a ce problème. icc utilise l'instruction assembleur sarb tandis que gcc utilise shrb. Gcc n'a pas ce problème shrb faisant ce que tu veux...

    Sur un Itanium, les deux compilateurs rendent bien 1.

    C'est peut-être un problème d'option...

    Espérant que cela te donnera une piste,
    Jc
    Merci. Ce qui m'intéresse c'est surtout le résultat avec icc sur Itanium.

    Il s'agirait donc d'un bug d'icc sur architecture ix86 (edit: sur laquelle je travaille).

  9. #9
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    C'est visiblement un mauvais de la part d'icc... En discutant avec un autre informaticien, on a commencé à regarder de plus près. Il semblerait que icc utilise la mauvaise instruction assembleur lorqu'il s'agit de unsigned char et unsigned short.

    Il utilise un shift signé ce qui fait que forcément lorsque tu donnes une valeur de 128 à un caractère non signé, le shift signé te retourne 192...

    Ceci est aussi vrai pour les shorts lorsque le bit de poids fort est mis à 1 mais pas pour les entiers puisqu'à ce moment là, il utilise une autre technique assembleur pour faire le calcul...

    Jc

    Remarque: en -O0, nous n'avons plus ce problème...

  10. #10
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par fearyourself
    C'est visiblement un mauvais de la part d'icc... En discutant avec un autre informaticien, on a commencé à regarder de plus près. Il semblerait que icc utilise la mauvaise instruction assembleur lorqu'il s'agit de unsigned char et unsigned short.

    Il utilise un shift signé ce qui fait que forcément lorsque tu donnes une valeur de 128 à un caractère non signé, le shift signé te retourne 192...

    Ceci est aussi vrai pour les shorts lorsque le bit de poids fort est mis à 1 mais pas pour les entiers puisqu'à ce moment là, il utilise une autre technique assembleur pour faire le calcul...
    Je sais bien que tout le monde peut faire des erreurs, mais c'est quand même fabuleux qu'il y ait un bug aussi énorme dans un compilateur Intel (payant en plus).

    Ceci-dit, il y a peut être une version plus récente qui corrige le bug...
    Pas de Wi-Fi à la maison : CPL

  11. #11
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par divad38
    Par contre, dans les cas suivants ça affiche 1:
    1) v >>= 7;
    2) en déclarant "v" sans le mot-clé "volatile"
    3) en compilant avec gcc sur iX86, gcc ou cc sur architecture Sparc.

    Etrange...
    Logique:

    1) il utilise l'instruction shift non signé
    2) sans le volatile, il fait le calcul numérique avant
    3) gcc ne fait pas cette "erreur"

    Jc

  12. #12
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Ceci-dit, il y a peut être une version plus récente qui corrige le bug...
    J'utilise icc version 9.0 et je suis d'accord avec toi, cela me paraît étonnant...

    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
     
    #include <stdio.h>
     
    int main(void)
    {
    volatile unsigned char a = 1<<7;
    volatile unsigned short b = 1<<15;
    volatile unsigned int c = 1<<31;
     
    a = a >> 7;
    b = b >> 7;
    c = c >> 7;
     
    printf("Value of a is: %d\n", a);
    printf("Value of b is: %d\n", b);
    printf("Value of c is: %d\n", c);
    return 0;
    }
    Avec l'option -O0:
    value of a is : 32
    value of b is : 8192
    value of c is : 536870912
    Avec l'option -O1:
    value of a is : 224
    value of b is : 57344
    value of c is : 536870912
    Je sens qu'un mail vers les mecs d'intel va se faire...

  13. #13
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Je sais bien que tout le monde peut faire des erreurs, mais c'est quand même fabuleux qu'il y ait un bug aussi énorme dans un compilateur Intel (payant en plus).

    Ceci-dit, il y a peut être une version plus récente qui corrige le bug...
    Ma version de compilateur est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $ icc -V
    Intel(R) C Compiler for 32-bit applications, Version 9.0    Build 20051201Z Package ID: l_cc_c_9.0.030
    Copyright (C) 1985-2005 Intel Corporation.  All rights reserved.
    Donc d'après vous ce serait un bug ?

  14. #14
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Comme si l'on n'avait pas assez de problèmes avec les volatiles

  15. #15
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par divad38
    Donc d'après vous ce serait un bug ?
    A mon avis, soit l'utilisation qu'on fait des volatiles est mauvaises (bien que...), soit effectivement un problème de leur côté... Un mail est déjà envoyé...

    Jc

  16. #16
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par fearyourself
    Citation Envoyé par divad38
    Donc d'après vous ce serait un bug ?
    A mon avis, soit l'utilisation qu'on fait des volatiles est mauvaises (bien que...), soit effectivement un problème de leur côté... Un mail est déjà envoyé...

    Jc
    Ok

    En fait, je n'ai pas réussi à écrire un exemple simple sans "volatile", mais à l'origine j'ai découvert ce problème dans un gros programme qui ne contient pas une seule fois le mot-clé "volatile".

    Il s'agit d'un programme qui tourne depuis des années sans problème avec toutes sortes de compilateurs et sur toutes sortes d'architectures différentes... jusqu'au jour où l'on a décidé d'utiliser icc !

    Autant dire qu'on a mis du temps à le débusquer, ce bug...

  17. #17
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    C'était bien un bug du compilateur intel, il l'ont corrigé dans leur dernière version 9.0.031...

    Bien trouvé,
    Jc

  18. #18
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par fearyourself
    C'était bien un bug du compilateur intel, il l'ont corrigé dans leur dernière version 9.0.031...

    Bien trouvé,
    Jc
    Je viens de voir ça !

    J'ai juste perdu une petite demi-journée à le débusquer...
    Bravo à Intel pour leur réactivité en tout cas !

  19. #19
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par divad38
    Citation Envoyé par fearyourself
    C'était bien un bug du compilateur intel, il l'ont corrigé dans leur dernière version 9.0.031...
    Jc
    Bravo à Intel pour leur réactivité en tout cas !
    Effectivement. Surtout que tu avais le build précédant 9.0.030...
    Pas de Wi-Fi à la maison : CPL

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

Discussions similaires

  1. [text] probleme avec simple quote
    Par bor1s dans le forum Langage SQL
    Réponses: 3
    Dernier message: 22/12/2005, 16h03
  2. Probleme avec encodage de simple quote
    Par linkowich dans le forum Langage
    Réponses: 2
    Dernier message: 31/10/2005, 13h16
  3. Réponses: 2
    Dernier message: 30/08/2004, 14h48

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