Basierend auf dieser interessanten Frage: Addition von int und uint und herumspielen mit konstanter Faltung wie erwähnt in Nicholas Carey Antwort , ich bin auf ein scheinbar inkonsistentes Verhalten des Compilers gestoßen:
Betrachten Sie das folgende Code-Snippet:
%Vor% Hier löst der Compiler k
korrekt in long
auf. Dieses spezielle Verhalten ist in den Spezifikationen genau definiert, wie in den Antworten auf die zuvor genannte Frage erläutert.
Was mich überrascht hat, ist, dass sich das Verhalten im Umgang mit literalen Konstanten oder Konstanten ändert. Ich habe die Antwort von Nicholas Carey gelesen Ich habe festgestellt, dass das Verhalten inkonsistent sein kann, also habe ich überprüft und bin mir sicher:
%Vor% k
wird in diesem Fall in Uint32
aufgelöst.
Gibt es einen Grund dafür, dass das Verhalten bei Konstanten anders ist oder ist das ein kleiner, aber unglücklicher "Fehler" (Fehlen eines besseren Begriffs) im Compiler?
Aus der C # -Spezifikation Version 5 , Abschnitt 6.1.9, Konstante Ausdrücke erlauben nur die folgenden impliziten Konvertierungen
6.1.9 Implizite konstante Ausdrucksumwandlungen
Eine implizite Konvertierung von konstanten Ausdrücken erlaubt die folgenden Konvertierungen:
* Ein Konstantenausdruck (§7.19) vom Typint
kann in den Typsbyte
,byte
,short
,ushort
,uint
oderulong
konvertiert werden, sofern der Wert der Konstante angegeben wird -expression liegt im Bereich des Zieltyps.
• Ein Konstantenausdruck vom Typlong
kann in den Typulong
konvertiert werden, vorausgesetzt, der Wert des Konstantenausdrucks ist nicht negativ.
Beachten Sie, dass long
nicht in der Liste der int
-Konvertierungen aufgeführt ist.
Die andere Hälfte des Problems ist, dass nur eine kleine Anzahl von numerischen Promotionen für binäre Operationen passieren:
(Aus Abschnitt 7.3.6.2 Binäre numerische Werbung):
- Wenn einer der Operanden vom Typ dezimal ist, wird der andere Operand in dezimal konvertiert, oder es tritt ein Bindungszeitfehler auf, wenn der andere Operand vom Typ float oder double ist.
- Andernfalls, wenn einer der Operanden vom Typ double ist, wird der andere Operand in double konvertiert.
- Andernfalls, wenn einer der Operanden vom Typ float ist, wird der andere Operand in den Typ float konvertiert.
- Andernfalls wird, wenn einer der Operanden vom Typ ulong ist, der andere Operand in den Typ ulong konvertiert oder es tritt ein Bindungszeitfehler auf, wenn der andere Operand vom Typ sbyte, short, int oder long ist.
- Andernfalls, wenn einer der Operanden vom Typ long ist, wird der andere Operand in den Typ long konvertiert.
- Andernfalls, wenn einer der Operanden vom Typ uint ist und der andere Operand vom Typ sbyte, short oder int ist, werden beide Operanden in den Typ long konvertiert.
- Andernfalls, wenn einer der Operanden vom Typ Uint ist, wird der andere Operand in den Typ Uint konvertiert.
- Ansonsten werden beide Operanden in den Typ int.
konvertiert
ERINNERN SIE SICH: Die int
to long
Konvertierung ist für Konstanten verboten, was bedeutet, dass beide Argumente stattdessen in uint
s hochgestuft werden.
Tags und Links c#