(true == true) ist leider false ...



  • Hallo,

    wir benutzen C++ Builder XE2. Im folgenden Code ist c leider false, obwohl a und b true sind. Kann mir nicht helfen.

    ..
    bool a = kalMess.getStatus(i);
    bool b = kalMess.getDone(i);
    bool c = (a == b);
    ..
    

    Habe das Projekt bereinigt, alle obj-Dateien usw gelöscht und komplett neu erzeugt. C++ Builder neu gestartet. Das half alles nichts.

    getStatus() und getDone() sind inline und const.

    Habe die Elemente untersucht, die Ausdrücke untersucht etc. Sie sind wirklich true, c halt false.



  • Wie ist es hiermit?

    bool c = (a && b) || !(a || b);
    

    Falls das das richtige Ergebnis liefert, schau dir mal die binären Werte von a und b im Debugger an (CPU-View oder Speicheransicht), oder evaluiere sowas wie (int)*(unsigned char*)&a .

    Ich bin nicht sicher, ob der C++Builder sich hier standardkonform verhält, aber ich fürchte schon...



  • Geben die beiden Funktionen denn direkt ein bool zurück? (Sonst halt einfach doppelt negieren !! .)



  • Es gibt zwei Möglichkeiten: Du irrst dich (z.B. mit Optimierungen gebaut und dann debuggt o.ä.) oder dein Compiler ist kaputt. Es gibt keinen Grund, warum das nicht funktionieren sollte.



  • Theoretisch ist auch möglich, dass es um einen Murks mit defines geht. #define bool int könnte sowas verursachen.

    Oder, vielleicht... weiss nicht:

    bool store_in_bool(char value)
    {
        union
        {
            bool as_bool;
            char as_char;
        } result;
    
        result.as_char = value;
        return result.as_bool;
    }
    
    int main()
    {
        const bool a = store_in_bool(1);
        const bool b = store_in_bool(3);
    
        assert(a); assert(b); assert(a == b);
    
        return 0;
    }
    

    Könnte eventuell beim Compiler irgendwas dummes machen?



  • Habe den Fehler gefunden, was mich noch stutziger macht. Die Inline Funktionen haben dummerweise den bool eines bool Arrays von der Stelle [0-1] zurückgegeben. Schlecht programmiert würde ich sagen.

    Aber warum zum teufel meckert CodeGuard nicht oder warum wird keine Exception geworfen? 😮



  • Vielleicht zeigst du uns mal den Quelltext, der das Verhalten verursacht. Im Moment kann ich mir nicht mehr so ganz vorstellen, was du eigentlich tust und was da passiert.



  • const int MAX_CHAN = 4;
    ...
    bool getStatus(unsigned short chan) const {return status[chan-1];}
    bool getDone(unsigned short chan) const {return done[chan-1];}
    ....
    bool status = true;
    
    // for (int i = 1; i <= MAX_CHAN; i++) //richtig
    for (int i = 0; i < MAX_CHAN; i++) // verursacht das (true && true) = false ist
    {
        status = status && (kalMess.getStatus(i) == kalMess.getDone(i));
    }
    


  • Unvollständig.

    bool getStatus(unsigned short chan) const {return status[chan-1];}
    bool getDone(unsigned short chan) const {return done[chan-1];}
    

    In die Arrays haste offenbar Nicht-bools reingeschrieben.
    Per reinterpret_cast oder warscheinlicher benachbarten Speicher überschrieben.

    Würde erstmal an sowas denken:

    assert(*(char*)*status[chan-1]==!!*(char*)*status[chan-1]);
    


  • Habe die Hälfte vergessen. Ich habe nur bools in das Array gesteckt.

    const int MAX_CHAN = 4;
    ...
    void setStatus(unsigned short chan, bool val) {status[chan-1] = val;}
    void setDone(unsigned int chan, bool val) {done[chan-1] = val;}
    ...
    bool getStatus(unsigned short chan) const {return status[chan-1];}
    bool getDone(unsigned short chan) const {return done[chan-1];}
    
    ....
    struct comTeleKal {
        unsigned int serialNo;
        unsigned int chanNum;
    ..
        bool status;
    };
    ...
    COM->Handler:
    bStatus = (status == 0 ? false : true);
    itsLastKalTeleGet.status = bStatus;
    ...
    void kalibrierung::setFullByTele(comTeleKal *pTele)
    {
        serialNo                    = pTele->serialNo;
    ..
        status[pTele->chanNum-1]    = pTele->status;
        done[pTele->chanNum-1]      = true;
    ..
    }
    
    ...
    bool status = true;
    
    // for (int i = 1; i <= MAX_CHAN; i++) //richtig
    for (int i = 0; i < MAX_CHAN; i++) // verursacht das (true && true) = false ist
    {
        status = status && (kalMess.getStatus(i) == kalMess.getDone(i));
    }
    


  • Kann in

    status[pTele->chanNum-1]    = pTele->status;
    

    pTele->status eine wirre Zahl stehen? Und ist der typ schon bool, daß sich der Compiler drauf verläßt, daß da nur 0 oder 1 drinsteht?
    Sowas wie eine 2?

    bStatus = (status == 0 ? false : true);
    

    Ja, genau. Wenn status kein bool ist, aber bStatus ein bool ist, macht der Compiler das auch von alleine.
    Wenn beides keine bools sind, muss man selber

    bStatus = (status == 0 ? false : true);
    

    machen oder

    bStatus = bool(status);
    

    //ergibt vollkommen nutzlose Warung auf MSVC.
    oder

    bStatus = !!status;
    

    //Standard-Version auf MSVC

    Wenn beide bool sind, macht der Compiler natürlich nix.
    Falls ein Schelm mal schrieb *(char)&status=2 dann denkt sich der ompiler da nix dabei und nachher steht in bStatus auch eine 2.
    Schlimmer noch, ich fürchte, der Optimierer darf bool() und ?false:true und !! einfach wegoptimieren, weil er ja "weiß", daß status schon bool ist und also nur 0 oder 1 drin haben kann.


Anmelden zum Antworten