none
Bug chez microsoft ? RRS feed

  • Question

  • Bonjour,

    je suis surpris par le code suivant qui renvoie une exception en mode débogage :

     

    #include <iostream>

    using namespace std;

    int main()

    {

    string ch="é";

    cout << isspace(ch[0]) << endl;

    return 1;

    }

    on peut pas faire plus simple.

    il semble que le compilateur ne connaisse pas les accentués : je suis sous Visual C++ 2008 Express version francaise et il semble que le compilateur ne trouvant pas le code pour le "é" renvoie une exception. Aucun compilateur jusque là ne m'avait fait ce "coup" là !

    comment dévalider cette exception qui n'a pas lieu d'être et faire en sorte que Visual renvoie un code correct (0 en l'occurence)

    merci pour toute information par avance

    mardi 31 août 2010 16:06

Réponses

  • heu, je suis peut etre bigleu, mais mon fichier source  est bien en ANSI codé sur 8 bits et non sur 16 bits, un simple éditeur hexa me le montre, et dans la page de propriété du projet , onglet Paramètres par défaut du projet|Jeu de caractères je ne vois bien que trois options :

    1) non défini

    2) Utiliser le jeu de caractères Unicode

    3) Utiliser le jeu de caractère multioctet (MBCS)

    n'ayant pas SBCS, je suis bien obligé de prendre MBCS, de plus microsoft semble tout convertir en 16bits même si j'étais en SBCS. Bon d'accord, il faut bien se mettre à unicode mais quelle galère pour tous les codes caractères anciens sur 8 bits et puis les routines sont conservées avec 8 bits : ca fait pas trés propre que isspace('é') fonctionne trés bien en mode non débug et qu'il plante en mode debug ! que le compilateur ait envoyé un warning, ok! mais pas plus...

    Tout cela pour me convaincre que l'on ne peut plus faire l'impasse sur l'unicode  (peut etre aussi avec les autres compilateurs d'ailleurs) : mais alors que l'on vire toutes les procedures de caractère sur 8 bits et que l'on ne donne pas la fausse impression qu'il puisse y avoir compatibilité.

    D'ailleurs je n'ai pas fouillé mais je suis persuadé que tout est codé en unicode dans le binaire résultant ce qui explique une augmentation du code binaire de plus de 30%

    Bon il y a moyen de biaiser en mettant isspace(unsigned char('é)), mais je suppose que ce sera toutes les procédures pareil (soupir) :)

    merci quand même :  j'en apprends tous les jours.

     

    cordialement

    • Marqué comme réponse c.panel vendredi 3 septembre 2010 12:02
    vendredi 3 septembre 2010 12:01

Toutes les réponses

  • Je pense que le problème n'est pas dans le compilateur mais dans l'éditeur.

    Vous utilisez vraisemblablement l'editeur de VS qui est UNICODE par défaut.

    Je pense que le code source de "é" est une séquence UNICODE que votre programme (ASCII orienté, old-school, borderline du C++ ("é" c'est pas super standard), au demeurant) ne sait pas interprété.

    Vous êtes dans un domaine qui est un non-standard-land.

    Utilisez les API unicode si vous utilisez des accents. Si vous êtes obligé d'utiliser des ASCII, pensez à utiliser correctement ces API et utilisez autant que possible les MultiBytes.

     

    P.S.: je pense que le bug est entre la chaise et le clavier. ;-)


    Paul Bacelar, Ex - MVP VC++
    mardi 31 août 2010 17:48
    Modérateur
  • bonsoir,

     

    je trouve quand même assez curieux que le code généré dépende alors de la manière dont est écrit le source, et d'autre part, j'utilise forcément les multibytes (dans le projet), l'EDI ne fournissant que cette option avec l'unicode.

    d'autre part j'ai tapé "é" single character et non wide character, je ne vois toujours pas pourquoi le compilateur irait interpréter cela comme un caractère unicode ou alors c'est que le compilateur ne peux gérer que de l'unicode.

    bref ! s'il y a un moyen de rendre ce code peut etre un peut vieillot mais tout a fait légal et executable (les compilateurs borland, GNU... le prenne sans problème), je serais quand même content de l'apprendre...

    merci !

    mardi 31 août 2010 19:16
  • C'est normal que le code soit fonction du code source, pas de la manière dont il est écrit.

    Avec du code ASCII, le même code source ne s'affiche pas de la même manière sur un éditeur que sur un autre, mais le compilateur sans fout, il ne l'affiche pas. Que la tabulation soit 4 ou 8 espaces, il n'en a que faire. Ce qui compte, c'est le code source, rien que le code source.

    Vous n'utilisez pas forcement le multibyte, c'est les options de compilation ET votre code qui le gère. Que l'EDI soit codé en UNICODE ou en multibyte n'a pas d'impact sur VOTRE code compilé et c'est encore heureux.

    Vous avez tapé "é" dans un éditeur de fichier qui a encodé ce caractère selon une "norme" qui n'est pas la même sur tous les éditeurs.

    Si votre fichier source est UNICODE, "é" est encodé en UNICODE, s'il est ASCII, il sera peut-être converti en UNICODE si vous faite des modifications dans l'éditeur de l'EDI VS. S'il est ASCII, comme "é" n'est pas un caractère ASCII standard, l'éditeur peut utiliser n'importe quel encodage qu'il souhaite. Cet encodage n'est pas forcément compatible avec les routines C++ que le programme utilise au moment de l'exécution. Le compilateur n'est coupable de rien. Il ne fait que compiler le code source qui est lui fonction de l'éditeur de texte (et de sa configuration).

    Ne vous braquez pas, le problème n'est pas dans le compilateur, mais dans le code source qui n'est pas "correcte". Un code source qui est fonction de l'éditeur de texte n'est pas sûr, donc, pour moi, incorrect.

    Vous considérez que le code est légal car il compile et s'exécute sur un ou deux compilateurs ?

    Pour moi, ce code n'est pas légal car l'encodage des caractères accentuées n'est pas spécifié dans la norme du C++ (tout du moins dans la version 98). Une chose non spécifiée n'est pas normalisée par Borland ou GNU. Et encore, ce n'est pas le compilateur qui est en faute mais l'éditeur de texte.

    Votre code n'est pas que vieillot mais non déterministe sans une spécification de la chaine de compilation, de l'éditeur de texte et du codepage courant lors de l'exécution du programme sous Windows. Ca fait plutôt limité comme champs déterministe.

    Cette limitation est dû à la qualité toute relative du code. C'est en cela que votre code n'est pas bon. Il est beaucoup trop dépendant d'éléments externes, et il y en a des éléments externes.

    Si vous voulez ne plus dépendre de ces détails, le plus simple est d'utiliser des chaines UNICODE (wstring à  la place de string) et d'avoir du code source en UNICODE. Si le code source UNICODE est trop galère, spécifiez vos chaines constantes en ressource du programme, comme le ferait tout programmeur "globalisation-internationalisation" responsable.


    Paul Bacelar, Ex - MVP VC++
    mercredi 1 septembre 2010 12:48
    Modérateur
  • heu, je suis peut etre bigleu, mais mon fichier source  est bien en ANSI codé sur 8 bits et non sur 16 bits, un simple éditeur hexa me le montre, et dans la page de propriété du projet , onglet Paramètres par défaut du projet|Jeu de caractères je ne vois bien que trois options :

    1) non défini

    2) Utiliser le jeu de caractères Unicode

    3) Utiliser le jeu de caractère multioctet (MBCS)

    n'ayant pas SBCS, je suis bien obligé de prendre MBCS, de plus microsoft semble tout convertir en 16bits même si j'étais en SBCS. Bon d'accord, il faut bien se mettre à unicode mais quelle galère pour tous les codes caractères anciens sur 8 bits et puis les routines sont conservées avec 8 bits : ca fait pas trés propre que isspace('é') fonctionne trés bien en mode non débug et qu'il plante en mode debug ! que le compilateur ait envoyé un warning, ok! mais pas plus...

    Tout cela pour me convaincre que l'on ne peut plus faire l'impasse sur l'unicode  (peut etre aussi avec les autres compilateurs d'ailleurs) : mais alors que l'on vire toutes les procedures de caractère sur 8 bits et que l'on ne donne pas la fausse impression qu'il puisse y avoir compatibilité.

    D'ailleurs je n'ai pas fouillé mais je suis persuadé que tout est codé en unicode dans le binaire résultant ce qui explique une augmentation du code binaire de plus de 30%

    Bon il y a moyen de biaiser en mettant isspace(unsigned char('é)), mais je suppose que ce sera toutes les procédures pareil (soupir) :)

    merci quand même :  j'en apprends tous les jours.

     

    cordialement

    • Marqué comme réponse c.panel vendredi 3 septembre 2010 12:02
    vendredi 3 septembre 2010 12:01
  • Si votre code source est en 8 bits, cela n'implique pas que votre exécutable généré utilise l'ASCII. L'un est complètement décorrélé de l'autre. C'est au programmeur de savoir ce qu'il fait. Et la manière dont est codé votre exemple montre une complète désinvolture sur cet aspect.

    Le paramètre du projet que vous mentionnez règle la version des primitives des chaînes de caractères et en aucun cas l'encodage des fichiers sources. C'est le BOM du fichier source qui pilote l'interprétation du charset du fichier source.

    Le code source est en ASCII (7bits), mais "é" n'est pas dans le jeu de caractère STANDARD de l'ASCII. La partie étendu de l'ASCII est fonction du "codepage" de l'exécutable.

    MBCS fonctionne parfaitement sur les ASCII standard. Une version "SBCS" est donc complètement inutile, à moins que vous voulez faire des programmes qui utilisent de l'ASCII étendu et qui ne fonctionnera que sur les machines(applications) ayant un "codepage" particulier. Cela ne fera que simplifier la génération de programme bogué. Vous pouvez toujours utiliser le transtypage en byte si cela vous amuse.

    La version Debug de la lib à juste l'amabilité de vous prévenir que vous êtes entrain de faire n'importe quoi, car votre caractère ASCII n'est pas compatible avec tous les Windows, mais bon, si vous voulez pas d'aide, au moins essayez de comprendre le pourquoi et ainsi vous pourrez passer outre.

    Votre code n'est pas bon, en ASCII comme en UNICODE.

    Si votre code augmente avec l'utilisation de l'UNICODE, c'est que vous avez un énorme problème de conception. Les chaînes de caractère d'un exécutable doivent être en ressource de votre programme et l'encodage UNICODE est la règle depuis au moins Win95.

    Une conception soignée et l'utilisation correcte des API et des outils vous simplifiera la vue et permettra d'éviter bon nombres de bugs.

    La version Debug de la STL est votre allié, pas votre ennemi.


    Paul Bacelar, Ex - MVP VC++
    lundi 6 septembre 2010 09:42
    Modérateur