Frage

Ich weiß, dass der ternäre Operator einige überraschende Einschränkungen hat, aber ich war ein bisschen verblüfft, dass dies für mich nicht kompiliert wird:

void foo(bool b)
{
    int* ptr =  ((b) ? NULL : NULL);
}

Offensichtlich ist das das Minimum, das erforderlich ist, um das Problem zu zeigen. Der Fehler ist:

[BCC32 Error] Unit11.cpp(20): E2034 Cannot convert 'int' to 'int *'

Der Compiler ist der weniger als 100%ige konforme Embarcadero C ++ Builder 2010, daher ist ein Compiler-Fehler alles andere als unmöglich ...

Hinweis: Parens modifiziert, um Verwirrung über meine Absicht zu vermeiden.

Note2: Ich hatte mich ein wenig verwirrt darüber, wie ich zu diesem Konstrukt an erster Stelle angekommen war a = b? c : d, wo B, C und D alle komplexe Ausdrücke waren. Um es einzugrenzen, ersetzte ich c und d mit NULLs, um zu überprüfen, ob b war der Täter. Zu diesem Zeitpunkt ging alles in einem Handcart zur Hölle.

War es hilfreich?

Lösung

NULL ist ein Makro, das sich ausdehnt 0 (oder ein integraler konstanter Ausdruck mit einem Wert von 0, zum Beispiel, (1 - 1)). Es ist sonst nicht "speziell".

Jeder integrale konstante Ausdruck mit einem Wert von Null ist als Nullzeigerkonstante verwendet, was der Grund ist int* ptr = 0; ist erlaubt. Hier ist der Ausdruck jedoch b ? 0 : 0; Dies ist kein integraler konstanter Ausdruck (b ist nicht konstant); Sein Typ ist int, was nicht implizit konvertierbar ist int*

Die Problemumgehung wäre, ausdrücklich festzustellen, dass Sie einen Zeigertyp wünschen:

int* const null_int_ptr = 0;
int* ptr = b ? null_int_ptr : null_int_ptr;

Das Beispiel ist jedoch etwas erfunden: Normalerweise, wenn man den bedingten Operator verwendet, ist mindestens eines der Argumente tatsächlich ein Zeigertyp (z. B. b ? ptr : 0); Wenn einer der Operanden ein Zeigertyp ist, ist die 0 wird implizit in denselben Zeigertyp konvertiert, und daher ist der Typ des gesamten bedingten Ausdrucks der Zeigertyp, nicht int.

Der einzige Fall, in dem Sie dieses "Problem" haben können, ist, wo eine Nullzeigerkonstante sowohl als zweite als auch als dritte Operanden des bedingten Operators verwendet wird, was ziemlich seltsam ist.

Andere Tipps

Ihr Problem ist das auf Ihrem System NULL ist definiert, um zu sein 0 Es wird angenommen, dass sie im Kontext des ternären Operators int ist. Wenn du static_cast einer der Operanden zu int* Es sollte automatisch die andere profomoten.

Aber warum verwenden ein solches Konstrukt überhaupt?

NULL könnte als Typ definiert werden int oder auch long, Daher hat der ternäre Operator den gleichen Typ. Es gibt keine implizite Konvertierung in den Zeigertyp, daher generiert Compiler einen Fehler. Das Gotcha hier ist, dass es eine implizite Umwandlung von einer konstanten Ganzzahl -Expression auf Null gibt (die berüchtigte Nullzeigerkonstante).

Mögliche Lösung hier ist eine explizite Besetzung:

int* ptr =  b ? (int*) NULL : NULL;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top