Typsicherheit char und wchar_t ???



  • Hallo,

    folgender Code compliliert ohne Fehler bzw. Warning (gcc). Wieso ? Wo bleibt die vielgepriesene Typsicherheit von C++ ??

    int main()
    {
       wchar_t wc;
       char c = 'a';
       wc = c;
       c = wc;
    }
    


  • Diogenes77 schrieb:

    Hallo,

    folgender Code compliliert ohne Fehler bzw. Warning (gcc). Wieso ? Wo bleibt die vielgepriesene Typsicherheit von C++ ??

    int main()
    {
       wchar_t wc;
       char c = 'a';
       wc = c;
       c = wc;
    }
    

    Wo ist das Problem? Immerhin bekommst du eine Warnung oder? 🙂



  • Nein, ich bekomme keine Warnung. Auch wenn sich der Thread pingelig anhört und einige hier sich darüber lustig machen, es hat mich in einem grösseren Projekt soeben einen halben Tag debugging gekostet. Ich habe ein UTF-8 File mit utf8_codecvt eingelesen, dann während der weiteren Verarbeitung an einer Stelle irrtümlich char statt wchar_t verwendet. Jene Zeichen, die mit wchar_t, aber nicht mit char darstellbar sind, sind dann sttillschweigend zu etwas ganz anderm "konvertiert" worden ... 😞



  • Bei Ganzzahltypen ist C++ für meinen Geschmack auch ein wenig freizügig in den Konvertierungen.

    Aber dieser Code funktioniert nur, weil der Compiler sieht, dass das Zeichen auf jeden Fall in den Typen passt. Teste mal diese leicht modifizierte Version:

    int main()
    {
       wchar_t wc = L'ß';
       char c = 'a';
       wc = c;
       c = wc;
    }
    

    Jetzt gibt's nen Fehler.

    Von daher: Dein Fehler liegt woanders.

    /EDIT: Quark. Der GCC beschwert sich über die ungültige Zeichencodierung der Eingabedatei. Sorry.



  • MSVC 8.0 schrieb:

    warning C4244: '=' : conversion from 'wchar_t' to 'char', possible loss of data

    Also bei mir kommt zumindest ein Warning. Von char nach wchar_t sollte kein Problem sein, und motzt er auch nicht an. Aber c = wc; motzt er mit einem Warning an.

    Wenn du kein Warning bekommst, ist dein Compiler schuld, und nicht C++. Vielleicht spuckt dein Compiler erst ein Warning aus, wenn du den Warning Level höher setzt?



  • Was für einen Compiler benutzt du denn?



  • Ich benutze g++ unter Ubuntu, als Warninglevel habe ich -Wall eingestellt.

    Zuweisung wc = c ohne Meldung zu akzeptieren ist selbstverstaendlich OK, da dabei kein Konvertierungsverlust eintreten kann. c = wc ohne Warning ist aber tueckisch ...



  • Quatsch. Erst jetzt ist mir aufgefallen, dass ich bei dem momentanen Projekt die Option -Wall irrtuemlich NICHT eingestellt hatte. Also der gcc warnt auch bei c = wc. Mea culpa ...



  • Diogenes77 schrieb:

    lso der gcc warnt auch bei c = wc. Mea culpa ...

    Nö:

    $ cat ch.cpp 
    #include <iostream>
    int main() {
        wchar_t wc = L'x';
        char c = wc;
        std::cout << c;
    }
    
    $ g++ -Wall -pedantic ch.cpp 
    $
    


  • Diogenes77 schrieb:

    Wo bleibt die vielgepriesene Typsicherheit von C++ ??

    Das Problem ist die Kompatibilität mit C, diese verlangt dieses Verhalten. Andernfalls müßte man einen Konversions-Cast-Operator einführen, den man immer dann benutzen muß, wenn man Typen mit einem größeren Wertebereich in Typen mit kleineren Wertebereich konvertieren will.

    Bei selbst definierten Klassen ist das übrigens kein Problem, da kann man Konversionskonstruktoren definieren, die diese Eigenschaft aufweisen. Nur wchar_t ist ein typedef und somit ein POD und erfüllt diese Bedingung nun einmal nicht - leider.



  • wchar_t ist kein typedef. Unter msvc ist er build-in, und so sollte es auch sein.



  • unicode-freak schrieb:

    Artchi schrieb:

    MSVC 8.0 schrieb:

    warning C4244: '=' : conversion from 'wchar_t' to 'char', possible loss of data

    Also bei mir kommt zumindest ein Warning.

    der umgekehrte fall ist gemeint, also wenn einem wchar_t ein char zugewiesen wird, du blitzmerker.
    🙂

    ähhh apropos "Blitzmerker": Nein, genau der von Artchi genannte Fall ist gemeint (wenn man versucht, ein wchar in ein char zu konvertieren ....
    Dass der andere Fall problemlos ist und auch zu keiner Warnung führen sollte, wurde bereits weiter oben geklärt....

    Hier hast Du Deine Steine zurück und die Telefonummer des Glasers....

    Gruß,

    Simon2.



  • typesafe-freak schrieb:

    Simon2 schrieb:

    ähhh apropos "Blitzmerker": Nein, genau der von Artchi genannte Fall ist gemeint (wenn man versucht, ein wchar in ein char zu konvertieren ....

    ich dachte der andere. wenn man ein wchar_t einem char zuweist ist's ja wohl klar dass da ein warning kommt, weil der wchar_t beschnitten werden muss.

    Es kommt ja aber im GCC 4.2 eben gerade *keine* Warnung.



  • Artchi schrieb:

    wchar_t ist kein typedef. Unter msvc ist er build-in, und so sollte es auch sein.

    Die ISO C Norm sagt nur, daß wchar_t in <stddef.h> als Typ definiert wird. Header müssen nicht als Dateien vorhanden sein, wenn doch dann ergibt sich zwangsweise, daß wchar_t ein typedef ist.



  • ~john schrieb:

    Artchi schrieb:

    wchar_t ist kein typedef. Unter msvc ist er build-in, und so sollte es auch sein.

    Die ISO C Norm sagt nur, daß wchar_t in <stddef.h> als Typ definiert wird.

    Wir sind hier aber im C++-Forum und der Standard sagt unter diff.wchar.t, dass das in C++ eben genau *nicht* dort definiert ist.

    /EDIT: 3.9.1.5 spezifiziert nochmal explizit, dass 'wchar_t' ein „distinct type“ ist – also kein typedef.



  • Konrad Rudolph schrieb:

    /EDIT: 3.9.1.5 spezifiziert nochmal explizit, dass 'wchar_t' ein „distinct type“ ist – also kein typedef.

    Tja, das kommt davon, wenn man in der falschen Norm nachschaut.



  • Konrad Rudolph schrieb:

    ...
    Es kommt ja aber im GCC 4.2 eben gerade *keine* Warnung.

    DAS habe ich auch nicht bestritten, sondern nur, dass Artchi eine Warnung im falschen Fall erwartet habe.
    Dass bei Deinem Compile keine Warnung erschien, habe ich durchaus zur Kenntnis genommen...

    Gruß,

    Simon2.



  • @Konrad
    Füge mal das Flag -Wconversion bei der Kompilierung hinzu, dann sollte auch eine Warnung kommen.


Anmelden zum Antworten