C-Style Cast vs static_cast



  • Hi,

    die Unterschiede der Casts sind mir bewusst.

    Aber ich habe dunkel im Kopf, dass Mal jemand hier meinte, dass er static_cast für ein einfaches int->float nicht verwendet.

    Bei mir ist es zurzeit so, dass ich ein Programm habe, bei dem ich hin und wieder float zu int und umgekehrt casten muss. Einfach, weil ich tatsächlich implizit das Runden ausnutzen möchte und zwar an unterschiedlichen Stellen.

    Würdet ihr da überall:

    static_cast<int>(static_cast<float>(socken) / muetzen + 0.5f); // Socken pro Mütze sei jetzt einfach Mal irgendeine Kennzahl z.B.
    

    nutzen?

    Oder doch lieber abgekürzt? Irgendwie sieht's ja schon etwas aufgebläht aus. 🙂

    Hoffe, das ist nicht zu schwammig.

    Beste Grüße,
    Eisflamme



  • hey

    ich verwende (fast) überall explizite static_cast s wo eine implizite konvertierung nicht mehr möglich ist, also wahrscheinlich auch in deinem code (wobei ich nicht weiss ob der äussere cast zum int nötig ist, je nach dem wofür das resultat dann eingesetzt wird...). um explizite konstruktoren von klassen aufzurufen verwende ich aber diese syntax:

    MyInst = MyClass(42);
    

    in so einem fall finde ich, dass es den konstrukoraufruf eher verdeutlicht als es ein static_cast tun würde.

    gruss.



  • Hi,

    stimmt, mein Beispiel war in dem Fall sinnlos. Habe es Mal mit "korrektem" Runden kombiniert.

    Also würdest Du da überall static_casts drumkloppen? Okay.


  • Mod

    Aber ich habe dunkel im Kopf, dass Mal jemand hier meinte, dass er static_cast für ein einfaches int->float nicht verwendet.

    Ja, ich. Und volkard, IIRC.

    Bei mir ist es zurzeit so, dass ich ein Programm habe, bei dem ich hin und wieder float zu int und umgekehrt casten muss. Einfach, weil ich tatsächlich implizit das Runden ausnutzen möchte und zwar an unterschiedlichen Stellen.

    Dafür gibt es std::floor - kannst du aber auch so machen wie du willst.

    Oder doch lieber abgekürzt?

    Oh ja - function-style-cast:

    int(float(socken) / muetzen + 0.5f)
    




  • Arcoth:
    Gibt es auch ne Begründung? 🙂


  • Mod

    Eisflamme schrieb:

    Gibt es auch ne Begründung? 🙂

    Ja. static_cast verwende ich ausschließlich bei Klassen. Siehe auch den Stackoverflow-Link.



  • Arcoth schrieb:

    Ja. static_cast verwende ich ausschließlich bei Klassen.

    C-Style-Casts bei Pointern sind böse.
    C-Style verwendet man nur bei arithmetischen Typen.


  • Mod

    Ich verwende nie C-Style, wieso zitierst du mich?
    In der Tat, ich nehme auch static_cast für Zeiger (in Klassenhierarchien) und für strongly typed enums . Also nicht ausschließlich für Klassen, wenn man die Terminologie streng nimmt. Aber es sind nun mal Zeiger auf Klassen...



  • Arcoth schrieb:

    Ich verwende nie C-Style, wieso zitierst du mich?

    Wenn du für Zeigerkonvertierungen keinrn static_cast verwendest, was verwendest du dann?

    In der Tat, ich nehme auch static_cast für Zeiger (in Klassenhierarchien) und für strongly typed enums . Also nicht ausschließlich für Klassen, wenn man die Terminologie streng nimmt. Aber es sind nun mal Zeiger auf Klassen...

    Die Argumentation trifft auf alle Zeiger zu, also auch die Konvertierung int* -> float*.



  • Arcoth schrieb:

    Eisflamme schrieb:

    Gibt es auch ne Begründung? 🙂

    Ja. static_cast verwende ich ausschließlich bei Klassen. Siehe auch den Stackoverflow-Link.

    Das ist keine Begründung, sondern eine Erklärung Deiner restlichen Konventionen.

    Also die Begründung, die ich vermute aber nicht sicher weiß: Aufgeblähter Code und mehr Tipparbeit sind die Nachteile der langen Schreibweise und für native Datentypen gibt es keinen Nachteil am (int)7.5 -Cast. Stimmt das?



  • Das schöne am static cast ist halt auch, man sieht das sofort/der fällt voll auf



  • Arcoth schrieb:

    Ich verwende nie C-Style

    ...wobei ich mich aber noch daran erinnern kann, wie ich feststellen musste, dass ein functional-style cast mehr als ein static_cast kann -- mal von Konstruktoren abgesehen, die mehrere Parameter haben wollen. Mit einem functional-style cast kannst du im Prinzip all das machen, was ein C-style cast auch kann, wenn ich mich da richtig erinnere. Und das ist IMHO irgendwie doof. Zumindest kompiliert sowas wie das hier:

    int blah(void* raw)
    {
      return int(raw);// hier äquivalent zu reinterpret_cast<int>(raw)
    }
    

    aber trotzdem benutz' ich den functional-style cast auch für numerisches Zeug, wenn ich zum Beispiel aus einem float ein int machen will, wobei die Nachkommastellen abgeschnitten werden. Das ist einfach kürzer so als ein static_cast.



  • hardware schrieb:

    Das schöne am static cast ist halt auch, man sieht das sofort/der fällt voll auf

    Und das betrachte ich bei numerischen, manchmal längere Formeln genau als Hässlichkeit.


  • Mod

    Eisflamme schrieb:

    Aufgeblähter Code und mehr Tipparbeit sind die Nachteile der langen Schreibweise und für native Datentypen gibt es keinen Nachteil am (int)7.5 -Cast. Stimmt das?

    Richtig.



  • Okay super, dann gewöhne ich mir das jetzt auch an. 🙂

    functional style cast vs C-Style wäre jetzt noch zu überlegen. Gibt es da Unterschiede? Soweit ich im Kopf habe, können die ja dasselbe. functional style hat für mich den optischen Vorteil, dass man deutlicher sieht, worauf sich der Cast bezieht.



  • Eisflamme schrieb:

    Aufgeblähter Code und mehr Tipparbeit sind die Nachteile der langen Schreibweise und für native Datentypen gibt es keinen Nachteil am (int)7.5 -Cast. Stimmt das?

    Nicht ganz. static_cast/reinterpret_cast etc. funktionieren mit den eingebauten Typen manchmal nicht richtig. Da will man immer den C-Cast um auf der sicheren Seite zu sein. Beispiele siehst du im SO-Link.



  • So toll ist der Link nicht, um alle Beiträge nur darauf basierend zu schreiben.

    Und etwas spezifischere Zitate wären auch hilfreich. Mein Lesen führte hierzu:

    your readers will scratch their heads and wonder if there's something they don't know about static_cast that makes it different from the C-style cast when applied to a number. (In fact, they are identical, but I had to read the relevant C++ spec section a couple times to be sure they were identical, and I still have the "something weird must be going on here" reaction.)

    also einem Widerspruch zu Deiner Aussage, dass static_cast sich anders als C-Cast verhält.



  • Hierzu noch etwas?

    functional style cast vs C-Style wäre jetzt noch zu überlegen. Gibt es da Unterschiede? Soweit ich im Kopf habe, können die ja dasselbe. functional style hat für mich den optischen Vorteil, dass man deutlicher sieht, worauf sich der Cast bezieht.


  • Mod

    Wie ich bereits gesagt habe, ich bevorzuge functional-style-cast.

    Stackoverflow ist da uebrigens falsch.

    The conversions performed by
    — a const_cast (5.2.11),
    — a static_cast (5.2.9),
    — a static_cast followed by a const_cast,
    — a reinterpret_cast (5.2.10), or
    — a reinterpret_cast followed by a const_cast,
    can be performed using the cast notation of explicit type conversion. The same semantic restrictions and behaviors apply, with the exception that in performing a static_cast in the following situations the conversion is valid even if the base class is inaccessible:
    — a pointer to an object of derived class type or an lvalue or rvalue of derived class type may be explicitly converted to a pointer or reference to an unambiguous base class type, respectively;
    — a pointer to member of derived class type may be explicitly converted to a pointer to member of an unambiguous non-virtual base class type;
    — a pointer to an object of an unambiguous non-virtual base class type, a glvalue of an unambiguous non-virtual base class type, or a pointer to member of an unambiguous non-virtual base class type may be explicitly converted to a pointer, a reference, or a pointer to member of a derived class type,
    respectively.

    functional-style-cast hingegen...

    A simple-type-specifier (7.1.6.2) or typename-specifier (14.6) followed by a parenthesized expression-list constructs a value of the specified type given the expression list.

    If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).

    [...]If the expression list specifies more than a single value, the type shall be a class with a suitably declared constructor (8.5, 12.1), and the
    expression T(x1, x2, ...) is equivalent in effect to the declaration T t(x1, x2, ...); for some invented temporary variable t, with the result being the value of t as a prvalue.


Anmelden zum Antworten