Frage zu Beispielcode aus 'Modern C++ Design' von Andrei Andrescu



  • Ich arbeite gerade das GENIALE buch 'Modern C++ Design' von Andrei Andrescu durch und habe eine kleine Frage zu einem Beispielcode.

    Andrescu stellt an einer stelle einen fantastischen code für eine safe_reinterpret_cast-funktion vor, welcher einen fehler wärend des debugging auswirft, wenn keine größenübereinstimmung zwischen den beiden datentypen vorliegt.

    Aber das ist eigenlich garnicht meine Frage, sondern ich frage mich ob die klasse ERROR_Destination_Type_Too_Narrow und CompileTimeChecker sich auf die Größe der .exe datei auswirken. Hierbei geht es mir nicht darum die paar byte zu sparen, sondern um ein generelles Verständnis davon, wie der code übersetzt wird.
    Werden derartige Klassen ohne "Inhalt" überhaupt in die .exe übernommen?

    Hier übrigens der Code (findet ihr übrigens im kapitel '2.1 Compile-Time Assertions') 😉

    template<bool> struct CompileTimeChecker
    {
    CompileTimeChecker(...);
    };
    template<> struct CompileTimeChecker<false> { };
    #define STATIC_CHECK(expr, msg) \
    {\
    class ERROR_##msg {}; \
    (void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg())));\
    }
    //////////////////////////////////////////////////////
    template <class To, class From>
    To safe_reinterpret_cast(From from)
    {
    STATIC_CHECK(sizeof(From) <= sizeof(To),
    Destination_Type_Too_Narrow);
    return reinterpret_cast<To>(from);
    }
    ...
    void* somePointer = ...;
    char c = safe_reinterpret_cast<char>(somePointer);
    


  • gamer8o4 schrieb:

    welcher einen fehler wärend des debugging auswirft

    Meinst du Kompilierung?

    Klassen werden generell nie ins Binary genommen, sondern nur Funktionen.

    Hier ist übrigens die C++11-Variante von deinem Code:

    template <class To, class From>
    To safe_reinterpret_cast(From from)
    {
      static_assert(sizeof(From) <= sizeof(To), "destination type too narrow");
      return reinterpret_cast<To>(from);
    }
    


  • okay danke 🙂 und ja ich meinte kompelierung.
    die c++11 variante hilft mir (leider) wenig, weil ich vs10 nutze und jaa.. das hat den standart soweit ich weiß noch nicht. 😕

    ich kapiere deinen code auch irgentwie nicht 😕 hast du das mit der fehlerfindung komplett rausgelassen? ich seh keine funktion die den fehler auslöst ? 😮

    ps: sorry, ja ich weiß dass der typ alexandrescu heißt ^^



  • Für solche Härtefälle wie dich gibt es Boost.StaticAssert.
    Ein einfaches define genügt:

    #define BOOST_STATIC_ASSERT_MSG static_assert
    

    Andreis Idee ist ja dieser STATIC_CHECK

    STATIC_CHECK(sizeof(From) <= sizeof(To), Destination_Type_Too_Narrow);
    

    Der Code obendran ist reiner Boilerplate um eine ansprechende Fehlermeldung zu erzeugen.



  • Visual C++ 2010 unterstützt static_assert und auch einige andere C++11-Features.



  • genial, fantastisch & schrieb:

    Klassen werden generell nie ins Binary genommen, sondern nur Funktionen

    ...und Objekte. Wenn du Objekte leerer Klassen erstellst, verbrauchst du doch 1 Byte. Bei leeren Basisklassen gibt es die Empty Base Optimization.

    Alexandrescu erwähnt das auch irgendwo in seinem Buch. Ich glaube, bei seinen Hierarchie-Generatoren.



  • Viel interessanter wäre für micht jetzt, ob diese Funktionen, die praktisch jeder Compiler überall inlinen wird (wenn man nicht gerade Debug-Builds macht), weil sie trivial sind, trotzdem einmal separat in der Binary landen.


  • Mod

    Decimad schrieb:

    trotzdem einmal separat in der Binary landen.

    Kommt auf die Art der Binary an: Bibliothek/Objektdatei? Ja klar, da kommt alles rein. Fertig gelinktes Programm? Sache des Linkers, aber eher nicht. Woher sollte der wissen, dass da früher mal ein Funktionsaufruf war? Und nicht benutzte Funktionen aus den Objektdateien kann und darf er weglassen.



  • gamer8o4 schrieb:

    Ich arbeite gerade das GENIALE buch 'Modern C++ Design' von Andrei Andrescu durch und habe eine kleine Frage zu einem Beispielcode.

    Also, mir kam das auch erst genial vor. Dieser Eindruck hat sich bei mir aber wieder verflüchtigt. Keine Ahnung, warum. Müsste da mal wieder durchblättern und gucken, was da eigentlich so drin steht. Das meiste lässt sich doch bestimmt unter "things you don't need to know" verbuchen.

    gamer8o4 schrieb:

    Andrescu stellt an einer stelle einen fantastischen code für eine safe_reinterpret_cast-funktion vor, welcher einen fehler wärend des debugging auswirft, wenn keine größenübereinstimmung zwischen den beiden datentypen vorliegt.

    Du meinst nicht "Debuggings" sondern "Kompilierens". Aha, ein reinterpret_cast von T* nach U*, der bei sizeof(T)<sizeof(U) einen Compile-Zeit-Fehler auswirft? Braucht man das?

    gamer8o4 schrieb:

    Aber das ist eigenlich garnicht meine Frage, sondern ich frage mich ob die klasse ERROR_Destination_Type_Too_Narrow und CompileTimeChecker sich auf die Größe der .exe datei auswirken. Hierbei geht es mir nicht darum die paar byte zu sparen, sondern um ein generelles Verständnis davon, wie der code übersetzt wird.
    Werden derartige Klassen ohne "Inhalt" überhaupt in die .exe übernommen?

    Nö. Und die Verwendung dessen im STATIC_CHECK Macro sollte wenigstens wegoptimiert werden.



  • Irgendwann gehen halt auch den besten Programmierern sinnvolle Anwendungsfälle für Templates aus! 😃



  • Du meinst nicht "Debuggings" sondern "Kompilierens". Aha, ein reinterpret_cast von T* nach U*, der bei sizeof(T)<sizeof(U) einen Compile-Zeit-Fehler auswirft? Braucht man das?

    Das Buch ist auch für meinen Geschmack ein wenig zuviel des Guten. Man lernt einige Elemente (Policy, Traits,...) kennen, wie sie in Container-Libs wie STL oder Boost verwendet werden. Und natürlich bergen diese Element auch die Gefahr das man Dinge over-designd.

    ABER !!!

    Ich habe schon C Projekte gesehen die Callback Funktion so benutzt haben dass man diese Klasse von Funktionen gut und gerne als Policy Element bezeichnen würde.



  • Also zum Buch, bei manchen Stellen fragt man sich zwar ob man das je brauchen kann, aber Grundlegende Designtechniken, wie eben die policies sind genail und genial erklärt.
    Ich war immer so einer der Templates nur für Container verwendet hat, bis mir jetzt aufgefallen ist, was man mit diesen Dingern alles machen kann.
    Ich bin zwar erst in kapitel 3, aber schon jetzt hat mir das Buch sehr geholfen, auch dabei ein besseres Gefühl für die Sprache zu bekommen (programmiere seit 2 jahren und naja, da gibt es natürlich noch viel zu leren 😉 )

    Zur eigentlichen Frage:
    Danke, habs verstanden 👍 😋



  • Ja, ein paar Konzepte von Modern C++ Design wird man selten bis nie brauchen. Dennoch fand ich das Buch ausserordentlich spannend zu lesen, alleine schon weil man sieht, was mit C++ alles möglich ist. Einige Kapitel haben mich auch zu Mechanismen inspiriert, die ich heute oft brauche.


Anmelden zum Antworten