Wann verwendet man bestimme Präprozessoranweisungen?



  • Hi,

    ich bin neu in der C++ - Welt und wollte mal fragen wann ich entsprechende Präprozessoranweisungen verwende wie:

    #if
    #elif
    #else
    #endif

    bzw. auch wann definiere ich eine Funktion oder Konstante über define und wann tue ich dies ganz normal über const?

    Ich weiß nicht warum mann 2 verschiedene Varianten benötigt. Könnte sich bitte irgendwer die Zeit nehmen dies zu erläutern?

    Danke im Voraus.

    MfG
    ich



  • Java ist übersichtlicher und einfacher.

    👍

    Es gibt keinen Grund, Funktionen oder Konstanten über Präprozessoranweisungen zu definieren.



  • Komisch schrieb:

    #if
    #elif
    #else
    #endif

    Meistens als Include Guard um mehrfaches "includieren" zu verhindern.
    Beispiel:

    #ifndef MY_HEADER_H_INCLUDED // noch nicht definiert? gut!
    #define MY_HEADER_H_INCLUDED // jetzt definieren
    // hier der Code der in den Header gehört
    #endif // block ende
    

    Einige Entwicklungsumgebungen erzeugen diese von sich aus.
    (Visual Studio verwendet "#pragma once", das im Grunde das Selbe tut, was aber nur Visual Studio kennt.)

    Komisch schrieb:

    bzw. auch wann definiere ich eine [...] Konstante über define und wann tue ich dies ganz normal über const?

    Immer const (oder mit constexpr oder enum. Kommt darauf an, was man braucht)

    Komisch schrieb:

    Ich weiß nicht warum mann 2 verschiedene Varianten benötigt. Könnte sich bitte irgendwer die Zeit nehmen dies zu erläutern?

    Manchmal möchte man Dinge vorverarbeiten lassen, oder aus dem code "entfernen" (über #if ...) bevor der compiler ran darf. (zB: für Workarounds im code für spezielle Compiler oder für platformabhängigen Code, den man ab- oder anschalten will.

    ==> Ich würde sagen: versuche einfach erstmal den Präprozessor nicht zu verwenden (Ausnahme: Include Guards).
    EDIT: und include selbst natürlich



  • Tim06TR schrieb:

    Visual Studio verwendet "#pragma once", das im Grunde das Selbe tut, was aber nur Visual Studio kennt

    Das kennen inzwischen die meisten.



  • [6.15] What does the FAQ mean by "such and such is evil"?

    FAQ: This means that a feature should be avoided whenever possible. The strong word is supposed to help people change their old thinking.

    FQA: This means the feature satisfies the following conditions:

    • It is inherited from C
    • It is easy to abuse (especially when it interacts with the new C++ features)
    • It can cause problems when abused (especially when it interacts with the new C++ features)
    • C++ provides one or more facilities duplicating the functionality of the feature, replacing the original problems with new and much more complicated problems

    For example, macros, pointers, and arrays meet this definition (the corresponding C++ "solutions" are const & template, references & smart pointers, and vector/string classes). Include files almost meet this definition, except that C++ doesn't duplicate this functionality (namespaces are a parallel notion of "modules", but they can't be used to locate definitions). Consequently, the FAQ will not call include files "evil". On the other hand, function overloading doesn't come from C, so duplicate facilities like template specialization, default arguments, etc. are not enough for the FAQ to call function overloading "evil". Still, function overloading is very commonly abused leading to major problems.

    A C++ user is likely to have a different definition of "evil". A user doesn't care whether something came from C or not, and whether C++ tried to offer duplicate facilities (while forcing users to deal with the original ones since they're still in the language). A user typically cares about the "easy to abuse and causing trouble when abused" parts. Lots and lots of parts of C++ are like that.

    As to the features the FAQ does call evil - why are they in the language? Is it good for the users of the language, or for those who designed and promoted it?

    Macros für Konstanten erfüllen diese Definition seit C++14 (nach dem man Konstanten-Templates definieren kann), Macros für bedingen Kompilierung nicht. D.h. if/elif/endif darfst du nach belieben verwenden.



  • Komisch schrieb:

    Ich weiß nicht warum mann 2 verschiedene Varianten benötigt. Könnte sich bitte irgendwer die Zeit nehmen dies zu erläutern?

    Versuch mal ein plattformübergreifendes Projekt ohne den Präprozessor zu schreiben.
    Ich weiss schon, das geht, aber lustig ist es nicht.



  • Beispiel:

    #ifdef OS_LINUX
    #define OS_STRING "linux"
    #elif defined(OS_WIN32)
    #define OS_STRING "win32"
    #else
    #error Unsupported OS!
    #endif
    
    int main()
    {
        std::cout << OS_STRING << std::endl;
    }
    

    Generell wenn du auf Betriebssystem, Plattform etc Rücksicht nehmen musst oder dem Nutzer die möglichkeit geben willst den Code zur Compilezeit über Preprozessoranweisungen zu konfigurieren.


Anmelden zum Antworten