Subtrahieren von Uint und Int und konstantes Falten

8

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?

    
InBetween 15.10.2014, 15:21
quelle

2 Antworten

4

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 Typ int kann in den Typ sbyte , byte , short , ushort , uint oder ulong konvertiert werden, sofern der Wert der Konstante angegeben wird -expression liegt im Bereich des Zieltyps.
  • Ein Konstantenausdruck vom Typ long kann in den Typ ulong 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.

    
Powerlord 15.10.2014 15:58
quelle
3

Sehen Sie sich diese Antwort an Jared Wadsworth 15.10.2014 15:39

quelle

Tags und Links