Frage zum präprozessor ( #if variable < X #error )



  • Hallo, ich wollte folgende Präprozessordirektive schreiben:

    const unsigned int key_length = 8;
    
    #if key_length < 6
        #error key_length too small! Must be 6 or greater!
    #endif
    

    Allerdings bekomme ich bei dem Code oben beim Kompilieren immer die Fehlermeldung. Wahrscheinlich liegt es daran, dass key_length nicht über #define "deklariert" wurde.
    Allerdings möchte ich es vermeiden, variablen über #define in meinen Code einzubinden.

    Gibt es eine Möglichkeit, über den Präprozessor eine zur Kompilierzeit initialisierte, konstante Variable auf einen bestimmten Wert zu überprüfen und bei Bedarf den Compiliervorgang abzubrechen?


  • Mod

    nein



  • Präpro schrieb:

    Gibt es eine Möglichkeit, über den Präprozessor eine zur Kompilierzeit initialisierte, konstante Variable auf einen bestimmten Wert zu überprüfen und bei Bedarf den Compiliervorgang abzubrechen?

    Nein, das geht nicht, weil der Präprozessor vor dem Compiler läuft.

    Was du aber zur Compilezeit tun kannst, sind Static Assertions. Durch ein bisschen googeln findest du sicher mehr darüber heraus, Boost hat zum Beispiel ein BOOST_STATIC_ASSERT Makro.



  • Mit #define kriegst du keine Variablen, sondern so etwas, wie Konstanten. Und warum sollte das nicht gut sein? - Für solche Sachen ist es ja (unter anderem) genau da.



  • Ich habs jetzt ein wenig umgebaut

    #define def_key_length 8
    
    #if def_key_length < 6
       #error too small
    #endif
    
    const unsigned int key_length = def_key_length
    

    So hab ich die Kontrolle zur Kompilierzeit und eine typsichere konstante Variable 😃



  • oder so:

    const unsigned int key_length = 8;
    
    #include <boost/static_assert.hpp>
    
    BOOST_STATIC_ASSERT(key_length >= 6);
    

    oder baust dir das selber:

    Vorraussetzung ist hier __COUNTER__ (sollte es imho aber sowohl unter MSVC als auch GCC geben).

    die ifndef sind unnütz, aber ist ja auch egal...

    Warum es MY_BUILD_VAR_NAME und MY_BUILD_VAR_NAME_ gibt? Weil sonst __COUNTER__ nicht ausgewertet werden würde...

    namespace my
    {
    	namespace detail
    	{
    		template<bool>
    		struct StaticAssert;
    
    		template<>
    		struct StaticAssert<true>
    		{};
    	}
    
    #	ifndef MY_BUILD_VAR_NAME_
    #		define MY_BUILD_VAR_NAME_( A, B )			A##B
    #	endif
    
    #	ifndef MY_BUILD_VAR_NAME
    #		define MY_BUILD_VAR_NAME( A, B )			MY_BUILD_VAR_NAME_(A,B)
    #	endif
    
    #	ifndef MY_GET_UNIQE_VAR_NAME
    #		define MY_GET_UNIQE_VAR_NAME( PRAEFIX )		MY_BUILD_VAR_NAME(PRAEFIX, __COUNTER__)
    #	endif
    
    #	ifndef MY_STATIC_ASSERT
    #		define MY_STATIC_ASSERT( CONDITION )		\
    		my::detail::StaticAssert<CONDITION> MY_GET_UNIQE_VAR_NAME(compile_time_assertion);
    #	endif
    
    }
    
    const unsigned int key_length = 8;
    MY_STATIC_ASSERT(key_length >= 6);
    

    bb


Anmelden zum Antworten