C vs C++ bei OSDEV



  • rüdiger schrieb:

    @abc.w
    size_t anstelle uint32_t!

    Ja... Hm, habe nur uint32_t und uint8_t als Datentypen.

    rüdiger schrieb:

    Aber der Code wirkt teilweise ein bisschen komisch... ...Grobe Fehler...

    Ja, zu viel von KISS (keep it sehr stupid)... 🙂 Ist sowieso nur zum Testen und Hauptsache, kein malloc(). Funktionierenden Kernel in C++ habe ich auch nicht und bin sehr weit davon entfernt, aber es hat seinen Reiz...



  • Erhard Henkes schrieb:

    Zeige mir eine konkrete Stelle in PrettyOS im Kernel, bei der uns C++ einen greifbaren Vorteil bringen würde.

    Im Moment könnte ich es ganz gut für das Kontrollieren des Interrupt-Flags gebrauchen (sti/cli):
    Wenn ich eine Routine schützen will, sieht das ja so aus:

    void foo()
    {
        cli();
    
        if ( x )
        {
            sti();
            return;
        }
    
        sti();
    }
    

    Das ist ja noch halbwegs OK. Das Problem dabei ist nur, dass foo u.U. eigentlich gar nicht die Interrupts anschalten darf. Z.B. wenn foo aus einer ebenfalls geschützten Funktion aufgerufen wird:

    void bar()
    {
        cli();
        foo();
        // Hier sind Interrupts leider wieder eingeschaltet
        doImportantStuff();
        sti();
    }
    

    D.h. wir brauchen eigentlich auch noch Abfrage, ob Interrupts beim cli-Aufruf gesetzt waren:

    void foo()
    {
        // cli sollte zurückgeben, ob Interrupts vorher gesetzt waren.
        bool interrupts_enabled = cli();
    
        if ( x )
        {
            if ( interrupts_enabled )
                sti();
            return;
        }
    
        if ( interrupts_enabled )
            sti();
    }
    

    Das an jeden Ausgang zu setzen, ist irgendwie eklig. Mit C++ wäre das doch eher einfacher:

    void foo()
    {
        DisableInterrupts interrupt_protection;
        // ...
    }
    


  • Man müsste ja noch bei jedem return aufpassen, die Interrupts wieder einzuschalten, was man in einem Destruktor machen könnte 🤡



  • abc.w schrieb:

    Man müsste ja noch bei jedem return aufpassen, die Interrupts wieder einzuschalten, was man in einem Destruktor machen könnte 🤡

    Darauf wollte ich eigentlich hinaus :p "DisableInterrupts" als Ersatz für das Ausschalten der Interrupts, merken ob sie an waren und gegebenenfalls wieder Anschalten der Interrupts beim rausspringen. Und das mit einem Einzeiler.


  • Mod

    Das Thema C vs C++ ist nicht neu:
    http://forum.osdev.org/viewtopic.php?f=15&t=22406&start=0

    Die Diskussion ist sehr unstrukturiert, aber einige Erfahrungsbeiträge sind lesenswert. In Summe gesehen gehen beide Sprachen, wenn man es richtig anpackt.

    Ich persönlich bin überrascht, wie gut man in C einen Kernel programmieren kann.
    Daher sehe ich keinen wirklichen Vorteil in C++.



  • Daher sehe ich keinen wirklichen Vorteil in C++.

    Ich sehe durchaus Vorteile. Funktionsüberladung ist immer gut^^, Dinge wie Listen ließen sich viel leichter nutzen (Konstruktoren/Destruktoren, u.a.), statt void* data mitzuführen könnte man einfach von einer Basisklasse Erben.



  • Das wichtigste: Information Hiding! Sprich Kapselung von Daten, so das man einen kontrollierten Zugriff erlauben kann. Völlig unabhängig von Vtable, Template-Bloat u.a. Mythen die Performanceverlust bedeuten sollen.

    Gerade die Kapselung kann viel zur Qualität eines Projektes (egal ob Kernel oder Anwendungen) beitragen. Sowohl weniger Fehler zur Laufzeit, als auch einer einfachen Wartung.


  • Mod

    Kapselung ( engl.: information hiding oder encapsulation ) ist in der Tat der wesentliche Effekt der Objektorientierung. Das ist ein klarer Pluspunkt für C++.
    http://www.henkessoft.de/C++/C++/kapselung.htm



  • Information Hiding kann man in C auch betreiben, aber Encapsulation nicht. Zwei Begriffe die nicht äquivalent sind.



  • Erhard Henkes schrieb:

    .. Ich persönlich bin überrascht, wie gut man in C einen Kernel programmieren kann. ...

    Liegt es vielleicht daran, dass die Tools gcc und binutils verwendet werden? 😉


  • Mod

    Dass man auch in C++ interessante OS bauen kann, wird hier von James Molloy und Jörg Pfähler ("bluecode") gezeigt:
    http://www.lowlevel.eu/wiki/Pedigree



  • Imo gibt es nur einen einzigen Grund heutzutage noch C zu benutzen: Wenn es für eine Zielplattform keinen C++ Compiler gibt. Alleine schon wegen templates, overloading und RAII würde ich mich jederzeit für C++ entscheiden wenn ich die Wahl hätte. Dass C++ einen inhärenten Performancenachteil gegenüber C hätte ist ein Märchen, man kann genausogut Beispiele aufzeigen wo das Gegenteil der Fall ist (z.B. das allseits beliebte std::sort vs qsort()). Natürlich hat C++ einige Sprachfeatures die einen gewissen Overhead mit sich bringen. Allerdings darf man dabei nicht vergessen dass, wenn man ähnliche Systeme direkt in C implementieren würde, am Ende C Code rauskommt der mehr oder weniger genau das tut was der C++ Compiler einem abnehmen würde und daher auch vergleichbaren Overhead mit sich bringt (Beispiel die gern verteufelten virtuelle Funktionen: In C greift man dafür eben in irgendeiner Form auf Function Pointer zurück und hat am Ende den selben Overhead).


  • Mod

    Information Hiding kann man in C auch betreiben

    Kannst du dies bitte an Beispielen darstellen?



  • foo.h:

    struct foo;
    
    struct foo* create_foo(void);
    void do_it(struct foo* xyz);
    

    foo.c:

    #include "foo.h"
    
    struct foo {
        int bar;
        char baz[42];
    };
    
    struct foo* create_foo(void) { return calloc(1, sizeof(struct foo)); }
    void do_it(struct foo* xyz) { ... }
    

    Von außen sieht niemand, wie eine struct foo tatsächlich aussieht, man hantiert nur mit Pointern darauf.



  • Stellen wir fest:
    1. Es ist sehr nützlich Kapselung/Information-Hiding (ich meine nicht Implementation-Hiding ähnlich Pimpl) zu betreiben.
    2. Es ist mit C-Mitteln in gewisser Weise möglich.

    Meine Frage: ist es in der C-Welt Usus, es so zu machen? Falls nicht, bitte ich um eine Erklärung, warum es nicht Usus ist. 😃



  • @taljeth
    Danke, genau sowas hatte ich Sinn.

    Man sieht aber auch es gibt Probleme, wenn man die Idee von vorher aufgreift, Polymorphie durch Funktionszeiger zu emulieren.



  • Artchi schrieb:

    Meine Frage: ist es in der C-Welt Usus, es so zu machen? Falls nicht, bitte ich um eine Erklärung, warum es nicht Usus ist. 😃

    Afaik is das was taljeth beschrieben hat in C eine relativ gängige Sache.


  • Mod

    http://d3s.mff.cuni.cz/publications/Decky-FormallyVerifiedOS.pdf
    Chapter 2.2 The C Programming Language:

    A large majority of OSes is coded in the C programming language (HelenOS is no exception to this). The choice of C in the case of kernel is usually wellmotivated, since the C language was designed specifically for implementing system software [10]: It is reasonably low-level in the sense that it allows to access the memory and other hardware resources with similar effectiveness as from assembler; It also requires almost no run-time support and it exports many features of the von Neumann hardware architecture to the programmer in a very straightforward, but still relatively portable way.

    However, what is the biggest advantage of C in terms of run-time performance is also the biggest weakness for formal reasoning. The permissive memory access model of C, the lack of any reference safety enforcement, the weak type system and generally little semantic information in the code – all these properties do not allow to make many general assumptions about the code.



  • ... However, what is the biggest advantage of C in terms of run-time performance is also the biggest weakness for formal reasoning. The permissive memory access model of C, the lack of any reference safety enforcement, the weak type system and generally little semantic information in the code – all these properties do not allow to make many general assumptions about the code.

    Viele Denkfallen und Fehler im C Quellcode lassen sich mit Hilfe der statischen Code-Analyse Tools wie splint aufdecken und vermeiden (es gibt auch entsprechende Tools für C++, kenne leider keine kostenlosen...).
    Das andere Problem und meiner Meinung nach, das schwergewichtigere, ist:

    In C, almost everything is left to the programmer who is free to set the rules.


  • Mod

    ... almost everything is left to the programmer who is free to set the rules.

    Entwickler eines eigenen OS schätzen diese Freiheiten und sollten damit auch umgehen können. 🙂


Anmelden zum Antworten