Seltsames Verhalten vom conditional operator



  • Hallo zusammen,

    ein Freund hat ein seltsames verhalten des conditional operators festgestellt und wir haben etwas herum probiert und haben nun im code folgendes Verhalten festgestellt:

    /*
       ... m_bBusy ist "false"
    */ 
    
    WCHAR * pRetText2 = !m_bBusy ? m_strText : m_bstrBusyText; // ok
    WCHAR * pRetText3 = m_bBusy ? m_bstrBusyText : m_strText;  // nicht ok --> Nachtrag: wenn man hier rein debugged dann wird so getan als sei m_strText ein BString.
    
    // !!! NACHTRAG !!!
    WCHAR * pRetText3 = m_bBusy ? m_bstrBusyText.m_str : m_strText;  // funktioniert
    

    Beide Zeilen machen eigentlich das gleiche, sie weisen pRetText im falle das m_bBusy false ist m_strText zu.

    Eigentl. sollte nun in dem Beispiel pRetText2 und pRetText3 beide auf m_strText zeigen ... komischer weise macht das nur pretText2 ... pRetText3 hat jetzt einen abweichenden Value und zeigt irgendwo ins nirvana.

    Was kann denn der Grund für solch ein Verhalten sein?

    Gruß
    Sascha


  • Mod

    Das Verhalten ist nicht nachvollziehbar:
    https://ideone.com/G7OJm7

    Folgerung: Der Fehler liegt (wie so oft) ganz woanders. Daher ist es wichtig, den Fehler richtig einzugrenzen. Im dritten Link in meiner Signatur steht erklärt, wie das geht und wie du hier den passenden Code zeigen kannst, falls du den Fehler damit noch nicht selber finden konntest.

    edit: Zu deinem Nachtrag: Du siehst ja schon selber, es war gar nicht der ternäre Operator, sondern es hat irgendetwas damit zu tun, wie deine Objekte genau definiert sind. Nun wissen wir natürlich nicht, was überhaupt hinter diesen (schrecklichen) Namen steckt, weil du es uns nicht gezeigt hast. Also können wir dir auch nicht helfen, bis du es tust.

    P.S.: Wieso benutzt du nicht einfach std::string? Ich kannte dieses "BString" bisher nicht, aber es scheint mir keine Vorteile zu bieten. Die Benchmarkergebnisse scheinen ziemlich getürkt zu sein. std::string ist sicherlich nicht das schnellste unter der Sonne, aber wer behauptet, einen C-String bei Zuweisung und Zugriff zu schlagen, der schummelt gewaltig. Ein Teil der Schummelei könnte sein, im Jahre 2010 Compiler aus dem Jahren 2003/2004 zu benutzen.



  • m_strText und m_bstrBusyText haben unterschiedliche Typen, richtig? Der Conditional-Ausdruck hat wie jeder (korrekte) Ausdruck einen zur Übersetzungszeit feststehenden Typ. Wenn die beiden Zweige unterschiedliche Typen haben, aber Umwandlungen möglich sind, muss der Compiler also irgendwie einen gemeinsamen Typen feststellen und dann die entsprechenden Typumwandlungen durchführen. Ich bin jetzt zu faul, die Regeln nachzuschlagen; aber vermutlich sind sie nicht symmetrisch, so dass er z.B. zuerst den Typ von dem ersten Zweig nimmt oder so. Ich hoffe das reicht als Ansatz für die Antwort.



  • Jap, die Typen sind unterschiedlich.

    Bashar schrieb:

    aber vermutlich sind sie nicht symmetrisch, so dass er z.B. zuerst den Typ von dem ersten Zweig nimmt oder so.

    Das beobachtete verhalten würde zudem passen, von daher denke ich dass deine Vermutung stimmt!

    Danke für die Antworten,
    Sascha


  • Mod

    Wenn ich das richtig zusammengoogle, dann ist
    BSTR = OLECHAR* (in Wirklichkeit ein Hybird aus Pascal- und C-style string, Nullterminiert mit 32-bit Längenangabe am Anfang, kann aber auch eingebette 0 enthalten)
    OLECHAR = wchar_t

    CString hat einen Konstruktor für LPCWSTR mit
    LPCWSTR = const wchar_t*

    Konsequenterweise ist BSTR implizit in CString konvertierbar, das Ergebnis aber völlig unbrauchbar 🙄


Log in to reply