Include Sentinel



  • Hi

    Ich hab folgendes in nem Code Beispiel gefunden.
    Und zwar in nem .cpp File (WinMain.cpp)

    #ifndef WINMAIN_H
    #include "WinMain.h"
    #endif
    //... Code hier
    

    im "WinMain.h" Header steht dann das mir bekannte:

    #ifndef WINMAIN_H
    #define WINMAIN_H
    
    //... Code hier
    
    #endif
    

    ich dachte, dass der Wächter im Header ausreichend ist,
    Ist das trotzdem empfehlenswert?

    thx



  • Hallo,
    diese sogenannten "internal" bzw. "redundanten" Include-Guards helfen bei großen Projekten und "dummen" Compilern/Präprozessoren die Compilezeit zu reduzieren.

    Angenommen du hast eine cpp-Datei die über Umwege zweimal ein

    #include "WinMain.h"

    enthält. Die normalen Include-Guards sorgen nun dafür, dass das Ergebnis korrekt ist (also Symbole nicht mehrfach in der Übersetzungseinheit auftreten). Trotzdem muss der Präprozessor die Datei WinMain zweimal öffnen und zweimal komplett lesen. Beim zweiten Durchlauf sieht der Präprozessor in der ersten Zeile, dass der Include-Guard gestzt ist. Auf der Suche nach dem passenden #endif muss er trotzdem alle nachfolgenden Zeilen lesen und anschauen.

    Hier helfen die redundanten Include-Guards. Diese sorgen dafür, dass eine Include-Datei pro Übersetzungseinheit garantiert nur einmal geöffnet werden muss.

    Bringen tun diese redundanten Include-Guards nur dann etwas, wenn dein Projekt eine gewisse Größe erreicht und bestimmte Header sehr häufig inkludiert werden (Beispiel: Header der Standardbibliothek).

    Mal davon abgesehen, dass moderne Compiler bessere Alternativen anbieten: Vorkompilierte Header, pragma once-Direktiven, "schlauere" Präprozessoren (die sich merken, welcher Header für welche ÜE schon gelesen wurde).

    Wenn du also nicht gerade eine BS-API oder eine hyperportable Standardbibliothek schreibst, kannst du meiner Meinung nach auf redundante Guards verzichten.



  • HumeSikkins schrieb:

    Hallo,
    diese sogenannten "internal" bzw. "redundanten" Include-Guards helfen bei großen Projekten und "dummen" Compilern/Präprozessoren die Compilezeit zu reduzieren.

    Du meinst VC++ 6 ist "dumm"? 😃
    Ich hab das Beispiel aus nem schon etwas älteren Artikel. Benutze selber aber 2005er Version von Visual Studio.

    HumeSikkins schrieb:

    Angenommen du hast eine cpp-Datei die über Umwege zweimal ein

    #include "WinMain.h"

    enthält. Die normalen Include-Guards sorgen nun dafür, dass das Ergebnis korrekt ist (also Symbole nicht mehrfach in der Übersetzungseinheit auftreten). Trotzdem muss der Präprozessor die Datei WinMain zweimal öffnen und zweimal komplett lesen. Beim zweiten Durchlauf sieht der Präprozessor in der ersten Zeile, dass der Include-Guard gestzt ist. Auf der Suche nach dem passenden #endif muss er trotzdem alle nachfolgenden Zeilen lesen und anschauen.

    Hier helfen die redundanten Include-Guards. Diese sorgen dafür, dass eine Include-Datei pro Übersetzungseinheit garantiert nur einmal geöffnet werden muss.

    Bringen tun diese redundanten Include-Guards nur dann etwas, wenn dein Projekt eine gewisse Größe erreicht und bestimmte Header sehr häufig inkludiert werden (Beispiel: Header der Standardbibliothek).

    Ok tönt verständlich. Macht dann durchaus auch Sinn.

    HumeSikkins schrieb:

    Mal davon abgesehen, dass moderne Compiler bessere Alternativen anbieten: Vorkompilierte Header, pragma once-Direktiven, "schlauere" Präprozessoren (die sich merken, welcher Header für welche ÜE schon gelesen wurde).

    Also benutze ich im VS besser generell #pragma once statt den Include Guards?

    HumeSikkins schrieb:

    Wenn du also nicht gerade eine BS-API oder eine hyperportable Standardbibliothek schreibst, kannst du meiner Meinung nach auf redundante Guards verzichten.

    Ne, sowas dann nicht. Es ist ein Artikel über DirectX8 und 2D Graphik mit nur einem File. Also wohl eher übervorsichtig der Author, oder aus Routine.

    Danke jedenfalls 👍
    man lernt nie aus
    bye

    edit: quote tags repariert



  • spricht nichts gegen pragma once, aber du solltest das pragma once in nen #ifdef-block packen

    ungefähr so

    #ifndef MY_HEADER_HPP
    #define MY_HEADER_HPP
    
    #ifdef _MSC_VER
    #pragma once
    #endif
    
    #endif
    

Anmelden zum Antworten