C-Style cast -> statich_cast<>()
-
@john-0 sagte in C-Style cast -> statich_cast<>():
lieber so
double progress = double(now)/double(total);Das ist kein Cast?
-
@MegaV0lt sagte in C-Style cast -> statich_cast<>():
@john-0 sagte in C-Style cast -> statich_cast<>():
lieber so
double progress = double(now)/double(total);Das ist kein Cast?
Technisch gesehen Nein, aber der Unterschied ist rein syntaktisch. Es sind zwei neue doubles, die mit den Werten von
now
undtotal
initialisiert werden, wozu diese Werte dann wiederum erst implizit als doubles interpretiert werden. Im Gegensatz zum Cast, wo diese Werte direkt explizit als double interpretiert werden. Ich weiß auch nicht, was john-0 dir damit sagen will. Beides nutzt die implizite Konvertierbarkeit von int nach double, genauso wie dein C++-style static_cast. Noch eine Möglichkeit, die implizit int nach double konvertiert:1.0 * now / total
. Such dir selber aus, welche Schreibweise du für die nützlichste hältst.Letztlich wird der Compiler aber den gleichen Code für alles erzeugen.
PS: Und falls du es bis jetzt nicht selbst gemerkt hast:
static_cast<double>(now / total)
ist wahrscheinlich nicht das, was du meintest. Denn da wird der Cast nach double ja auf das Ergebnis vonnow/total
angewandt. D.h. da passiert erst eine Ganzzahldivision mit Ganzzahlergebnis (im Typensinne), und das als double zu interpretieren, ändert nichts daran, dass das eine Ganzzahl ist (im mathematischen Sinne). Du willst den Cast auf (mindestens) eine Hälfte der Division anwenden, bevor diese passiert, nicht auf das Ergebnis.
-
Ok, bekomme allerdings mit
double(now)
Auch eine Warnung, dass die Syntax veraltet ist
Nach einigem "Googeln", werde ich das wohl so machen:double progress = now * 1.0 / total;
Edit: Gerade gesehen @SeppJ hat es ja auch so vorgeschlagen
-
Ich habe dir auch oben noch eine Erklärung gegeben, was an
static_cast<double>(now / total)
falsch ist, während du schon geantwortet hast.
-
@SeppJ sagte in C-Style cast -> statich_cast<>():
Im Gegensatz zum Cast, wo diese Werte direkt explizit als double interpretiert werden. Ich weiß auch nicht, was john-0 dir damit sagen will.
Man sollte in C++ die Konversion dem Cast vorziehen, wenn es dabei zu keinem Datenverlust kommt. Casts sind etwas besonders, und signalisieren, dass z.B. Informationen verloren gehen können. Wenn man nun jede x-beliebige Typkonversion mit einem Cast verdeckt, dann weist man der Aktion eine Bedeutung zu, die sie nicht hat. Nur ist der static_cast nicht wirklich geeignet an dieser Stelle, da er Grunde nichts besser macht. Aber es gibt immerhin beim Boost Projekt ein passenden Cast für diese Möglichkeit.
Leider gehört das Themengebiet zu den C Altlasten in C++, so dass das nicht so funktioniert wie es wünschenswert wäre.
#include <iostream> #include <cstdlib> #include <boost/numeric/conversion/cast.hpp> int main() { int x = 100000; short s1 = 0, s2 = 0, s3 = 0; double d = double(x); s1 = static_cast<short>(x); s2 = x; std::cout << x << "\n"; std::cout << d << "\n"; std::cout << s1 << ", " << s2 << "\n"; try { s3 = boost::numeric_cast<short>(x); std::cout << s3 << "\n"; } catch (std::exception& e) { std::cerr << "conversion failed\n"; std::cerr << e.what(); } return EXIT_SUCCESS; }
-
@SeppJ sagte in C-Style cast -> statich_cast<>():
@MegaV0lt sagte in C-Style cast -> statich_cast<>():
@john-0 sagte in C-Style cast -> statich_cast<>():
lieber so
double progress = double(now)/double(total);Das ist kein Cast?
Technisch gesehen Nein, [...]
Ich glaube schon, dass das ein Cast ist. Nennt sich functional-style cast expression, siehe Explicit type conversion, Syntax-Variante (2):
If there is exactly one expression in parentheses, this cast expression is exactly equivalent to the corresponding C-style cast expression.
Hab das auch lange Zeit wie einen Konstruktor gelesen. Aber wie man auch immer es nennt, am Ende kommt eh dasselbe bei raus, spätestens nach Optimierungen
-
@SeppJ sagte in C-Style cast -> statich_cast<>():
@MegaV0lt sagte in C-Style cast -> statich_cast<>():
@john-0 sagte in C-Style cast -> statich_cast<>():
lieber so
double progress = double(now)/double(total);Das ist kein Cast?
Technisch gesehen Nein, aber der Unterschied ist rein syntaktisch. Es sind zwei neue doubles, die mit den Werten von now und total initialisiert werden, wozu diese Werte dann wiederum erst implizit als doubles interpretiert werden. Im Gegensatz zum Cast, wo diese Werte direkt explizit als double interpretiert werden.
Das ist eine "functional-style cast expression", und diese ist für eingebaute Typen vom Verhalten her equivalent zum C-style cast.
Siehe https://en.cppreference.com/w/cpp/language/explicit_cast (2)
D.h. die Umwandlung ist sehr "explizit", man kann damit schliesslich auch z.B. Integers in Zeiger verwandeln - was mit impliziten Umwandlungen ja nicht geht. Für impliziten Umwandlung ist mir keine "inline" Schreibweise bekannt.
ps: Upps, das wurde ja gerade schon geschrieben. Aber löschen tu ich meins deswegen auch nicht
-
@Finnegan sagte in C-Style cast -> statich_cast<>():
Hab das auch lange Zeit wie einen Konstruktor gelesen. Aber wie man auch immer es nennt, am Ende kommt eh dasselbe bei raus, spätestens nach Optimierungen
Naja, der grosse Unterschied ist dass es halt ein C-style cast, aka. "halt die Klappe und mach es einfach" ist. Man kann damit also viel mehr Unsinn bauen als mit z.B.
Type{expression}
oderstatic_cast<Type>(expression)
.
-
@DocShoe sagte in C-Style cast -> statich_cast<>():
@MegaV0lt
Probier's doch einfach aus. Die Gemeinschaft ist kein Compiler, und deine Frage ist doch wirklich einfach selbst zu beantworten.Weil ich es nirgendwo erwähnt sah; @MegaV0lt , mach Dich mal mit einem Debugger vertraut. Da kannst Du i.d.R. die Werte der einzelnen Variablen überprüfen.
-
@hustbaer sagte in C-Style cast -> statich_cast<>():
@Finnegan sagte in C-Style cast -> statich_cast<>():
Hab das auch lange Zeit wie einen Konstruktor gelesen. Aber wie man auch immer es nennt, am Ende kommt eh dasselbe bei raus, spätestens nach Optimierungen
Naja, der grosse Unterschied ist dass es halt ein C-style cast, aka. "halt die Klappe und mach es einfach" ist. Man kann damit also viel mehr Unsinn bauen als mit z.B.
Type{expression}
oderstatic_cast<Type>(expression)
.Etwas späte Antwort, aber da stimme ich zu. Würde sich das - wie man es intuitiv erstmal liest - wie ein
T(T)
-Konstruktor verhalten, dann wäre das unterm Strich wie einstatic_cast
. Das würde daher nicht nur "Unsinn" vermeiden, wie du schreibst, sondern wäre auch irgendwie konsistenter, wenn es lediglich eine alternative Syntax fürstatic_cast
wäre.
-
@Finnegan Ich hab ehrlich gesagt auch lange Zeit gedacht dass es sich wie
static_cast
verhält. Und ich habe festgestellt dass ich damit nicht alleine bin. Viele C++ Entwickler, auch erfahrene, glauben dass es equivalent zustatic_cast
ist. Und so lange man nur Dinge damit castet die auch mitstatic_cast
gehen, ist es ja auch so.Würde sich das - wie man es intuitiv erstmal liest - wie ein T(T)-Konstruktor verhalten, dann wäre das unterm Strich wie ein static_cast.
Ich gehe mal davon aus dass du einen
T(T const&)
bzw.T(T&&)
Konstruktor meinst.
Und da verhält sichstatic_cast
schon anders, zumindest bei Zeigern. Denn da kannst du mitstatic_cast
ja auch Downcasts machen bzw. auch vonvoid*
zuT*
konvertieren.Die sicherste explizite Konvertierung ist
T{expression}
. Da sind z.B. auch "narrowing conversions" verboten. Obwohl GCC hier nur eine Warnung ausgibt (Clang, MSVC: Fehler). Wobei ich glaube dass das Verhalten von GCC standardkonform ist. Der Standard schreibt oft gar kein Verhalten bei "verbotenen" Dingen vor, und wenn, dann meistens nur dass es eine "diagnostic" geben muss. Und das ist auch mit einer Warnung erfüllt.
-
@hustbaer sagte in C-Style cast -> statich_cast<>():
Wobei ich glaube dass das Verhalten von GCC standardkonform ist. Der Standard schreibt oft gar kein Verhalten bei "verbotenen" Dingen vor, und wenn, dann meistens nur dass es eine "diagnostic" geben muss. Und das ist auch mit einer Warnung erfüllt.
Klar. Es ist aber auch irgendwie seltsam, dass GCC sich entscheidet, narrowing conversions zuzulassen, was anmutet wie eine Entscheidung um legacy Code zu unterstützen, wohingegen diese Syntax zum Zeitpunkt jener Entscheidung noch sehr jung gewesen sein muss. Ich bin mittlerweile auch u.a. diesem Grund einfach ein grösserer Fan von Clang. Move fast & break things
Was mich an dem Zustand der Syntax stört, ist auch die Tatsache, dass C-Style casts so viel einfacher zu tippen sind (ich hab keinen Bock
static_cast<>
auszuschreiben). Aber das sind eben diese historischen Tumore, die man nicht mehr exzisieren kann...
-
@Columbo sagte in C-Style cast -> statich_cast<>():
Klar. Es ist aber auch irgendwie seltsam, dass GCC sich entscheidet, narrowing conversions zuzulassen,
Ich sehe zu, dass auch alle Warnungen bei eigenem Code entfernt werden. Insofern macht das für mich keinen großen Unterschied, ob das nun Warnungen oder Fehler sind. Zudem existiert das Compiler-Flag "-Werror".
Was mich an dem Zustand der Syntax stört, ist auch die Tatsache, dass C-Style casts so viel einfacher zu tippen sind (ich hab keinen Bock
static_cast<>
auszuschreiben).C Casts sind aber immer die gleichen, und unterscheiden nicht nach den für C++ notwendigen Fällen.