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?
-
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
undMY_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