Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

Bedingte Bewertung mit konstanter Bedingung macht anschließenden Cast überflüssig, warum?
chriscolm
myCSharp.de - Member



Dabei seit:
Beiträge: 112

Themenstarter:

Bedingte Bewertung mit konstanter Bedingung macht anschließenden Cast überflüssig, warum?

beantworten | zitieren | melden

Hallo,

gerade über eine Merkwürdigkeit gestolpert:


bool test = false;
byte[] testArr = new byte[] { test ? 1 : 0 };
byte[] testArr_2 = new byte[] {false ? 1 : 0 };

Kann mit jemand erklären, warum die untere Zeile anstandslos kompiliert wird, die mittlere aber nicht? Die Fehlermeldung:
Fehler
Fehler 1 Der Typ "int" kann nicht implizit in "byte" konvertiert werden. Es ist bereits eine explizite Konvertierung vorhanden. (Möglicherweise fehlt eine Umwandlung.)

Grüße

Christian
private Nachricht | Beiträge des Benutzers
reloop
myCSharp.de - Member

Avatar #avatar-3256.jpg


Dabei seit:
Beiträge: 139

beantworten | zitieren | melden

Da an dieser Stelle ein Byte-Cast fehlt.

So sollte es funktionieren:

byte[] testArr = new byte[] { (byte) (test ? 1 : 0) };

Noch kurz zur Erklärung:

byte[] testArr_2 = new byte[] { false ? 1 : 0 };

Damit erzeugst du unerreichbaren Code. Somit ist vor dem Compile klar, dass es nur 0 sein kann.

Meiner Meinung nach wird es direkt so interpretiert:


byte[] testArr_2 = new byte[] { 0 };

Dadurch entsteht keine Umwandlung in Int, wie es oben der Fall ist.

Gruss,
reloop
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von reloop am .
private Nachricht | Beiträge des Benutzers
chriscolm
myCSharp.de - Member



Dabei seit:
Beiträge: 112

Themenstarter:

beantworten | zitieren | melden

na, mir ist schon klar, wie ich casten muss.
Mich interessiert halt, warum der Kompiler im einen Fall offenbar ein Integer sieht bzw nicht implizit casten kann, im anderen aber ein Byte.

byte[] testArr = new byte[]{true ? 1 : 0}
funzt übrigens auch. Ich meine, schließlich kann ich doch auch

byte b = 1;
deklarieren ohne dass der Kompiler meckert; hier findet ein impliziter Cast statt.

Grüße

Christian
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5.655
Herkunft: Leipzig

beantworten | zitieren | melden

Wenn du einfach nur "1" schreibst, nimmt der Kompiler Integer als Datentyp an. Integer ist nicht automatisch in ein Byte umwandelbar, daher kommt dein Fehler. Es hat nichts mit dem Boolean-Datentype zu tun!
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
winSharp93
myCSharp.de - Experte

Avatar #avatar-2918.png


Dabei seit:
Beiträge: 5.742
Herkunft: Stuttgart

beantworten | zitieren | melden

Hallo chriscolm,

tja - auch so ein Compiler wird nur von Menschen entwickelt

Ich gehe mal davon aus, dass implizite Konvertierungen zur Compilezeit im Compilingprozess vor der Behandlung des -Operators stattfinden.
Somit erkennt der Compiler nicht, dass er die 0 (ein int) gefahrlos in ein byte casten kann (geht nur, wenn der Wert in ein Byte "passt").

Bei der zweiten Variante wird vermutlich (relativ früh) eine Optimierung aktiv, die - wie das reloop schon angemerkt hat - erkennt, dass der Ausdruck immer zu "0" ausgewertet wird und setzt den Wert ein.
Daraufhin kann dann auch wieder implizit konvertiert werden.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo zusammen,

ich würde es doch eine Nuance anders sehen. Es kommt nicht darauf an, welchen Wert ein Ausdruck hat, sondern nur, ob es sich um einen literalen oder nicht-literalen Ausdruck handelt. Insofern liegt auch kein menschlicher Fehler oder ein Problem mit einer etwa übersehenen Auswirkung einer Optimierung vor, sondern alles works as designed.

Die folgenden Zitate stammen von byte (C# Reference)
Zitat
you can declare and initialize a byte variable like this example:

byte myByte = 255;
In the preceding declaration, the integer literal 255 is implicitly converted from int to byte. If the integer literal exceeds the range of byte, a compilation error will occur.

Für Integer-Literale gibt es also - wie auch schon gesagt wurde - eine implizite Konvertierung nach byte (sofern der Wertebereich stimmt).
Zitat
You cannot implicitly convert non-literal numeric types of larger storage size to byte.

// Error: conversion from int to byte:
byte z = x + y;

Für nicht-literale Ausdrücke gibt es also keine implizite Konvertierung nach byte (selbst dann nicht, wenn der Wertebereich stimmt).

Wenn man jetzt noch weiß, dass der Compiler literale Ausdrücke bereits zur Compilezeit zu literalen Werten ausrechnet, lüftet sich der Schleier. Folgendes ist möglich und produziert keine Compiler-Fehler:

byte z = 1 + 2;

Nun sind aber auch false ? 1 : 0 und true ? 1 : 0 literale Ausdrücke die der Compiler zu den (Integer-)Literalen 0 bzw. 1 ausrechnet. Wogegen der Ausdruck test ? 1 : 0 ein nicht-literaler (Integer-)Ausdruck ist. Im ersten Fall gibt es wie besprochen eine implizite Konvertierung, im zweiten Fall nicht. Deshalb muss man im zweiten Fall explizit casten.

herbivore

PS: Unerreichbarer Code wird durch einen literale bedingte Bewertung übrigens nicht produziert (folgerichtig gibt es auch keine solche Warnung), weil daraus ja überhaupt kein ausführbarer Code generiert wird, sondern der Ausdruck schon zur Compilezeit zu einem literalen Wert ausgerechnet wird. Der literale Wert ist dann zwar schon ein Integer, der aber als solcher implizit in byte gecastet wird.

PPS: Der Compiler sieht die fraglichen Ausdrücke/Werte immer als Integer, nie als byte, aber für Interger-Literale gibt es eben die implizite Konvertierung in byte.
private Nachricht | Beiträge des Benutzers
chriscolm
myCSharp.de - Member



Dabei seit:
Beiträge: 112

Themenstarter:

beantworten | zitieren | melden

Moin,

vielen Dank , speziell an herbivore, das ist schlüssig und nachvollziehbar.

Grüße

Christian
private Nachricht | Beiträge des Benutzers