Wieso Typprüfung bei Makros nicht möglich?
-
MSVC++ F1 sagt:
Vorlagen funktionieren in vieler Hinsicht wie Präprozessor-Makros, indem die Variable in der Vorlage einen gegebenen Typ erhält. Es gibt jedoch auch viele Unterschiede zwischen einem Makro wie diesem:
#define min(i, j) (((i) < (j)) ? (i) : (j))
und einer Vorlage:
template<class T> T min (T i, T j) { return ((i < j) ? i : j) }
Folgende Probleme ergeben sich mit dem Makro:
Es gibt für den Compiler keine Möglichkeit, zu überprüfen, ob die Makroparameter kompatible Typen haben. Das Makro wird ohne besondere Typprüfung erweitert.
Frage: wieso kann denn das Makro keiner Typprüfung unterworfen werden?
Soweit ich weiß, startet der Preprocessor vor dem Kompilieren; ergo müsste der Compilerer
den gesamten Code sehen können.Also wenn z.B. das Makro min(double_val, int_val) aufgerufen wird, dann steht da doch vor
dem eigentlichen Übersetzen der folgende Code:(((double_val) < (int_val)) ? (double_val) : (int_val))
Danke im Voraus
-
Makros werden vor dem Compiler ersetzt.
#define TEXT 12 int main() { int i = TEXT; };
bekommt der Compiler nurnoch zu sehen als:
int main() { int i = 12; };
Es ist eine reine Textersetzung. Und wenn da der Typ mit reingesetzt wird.
Es kommt auf der Ergebnis drauf an, wenn beim Ersetzen ein Typ dabei ist wird es auch eine Typprüfung geben....
-
Fast immer kann man Macros die den Type brauchen mit Inline und/oder Templates ersetzen. Allerdings wenn es nicht anders geht kannst du das hier versuchen:
template<typename T> inline T&check_type(T&t){return t;} #define min(a,b) ((check_type<int>(a)<check_type<int>(b))?(a):(b))
-
Knuddlbaer schrieb:
Makros werden vor dem Compiler ersetzt.
#define TEXT 12 int main() { int i = TEXT; };
bekommt der Compiler nurnoch zu sehen als:
int main() { int i = 12; };
Es ist eine reine Textersetzung. Und wenn da der Typ mit reingesetzt wird.
Es kommt auf der Ergebnis drauf an, wenn beim Ersetzen ein Typ dabei ist wird es auch eine Typprüfung geben....Was heißt: und wenn da der Typ mit reingesetzt wird?
Und gib bitte ein Bsp. dafür, wo nicht der typ dabei ist.
-
#define PREPRO_MIN(i, j) (((i) < (j)) ? (i) : (j)) struct Foo {}; int main () { Foo foo; int bar = 2; int x = PREPRO_MIN(foo, bar); return 0; }
Wäre es ein Template bekämst du eine aussagekräftige Fehlermelsung.
-
Im bereits gegebenen Beispiel ist im Makro kein Typ vorhanden.
Wenn man sich vor Augen führt was das Ersetzen von TEXT durch 12 bedeutet wird man sicherlich feststellen das es keinen Typ gibt für TEXT.Makros die mit Typen zu tun haben findet man z.B. in der WinAPI:
#define BOOL int; (oder so #ähnlich)
Hier wird BOOL durch int ersetzt und der Compiler kann dort durch diese Information prüfen ob das "BOOL" denn passt.
-
Eigendlich benutzt die WinAPI typedefs
-
*** schrieb:
Eigendlich benutzt die WinAPI typedefs
Nur in den neueren Header-Versionen.
-
der_held schrieb:
#define PREPRO_MIN(i, j) (((i) < (j)) ? (i) : (j)) struct Foo {}; int main () { Foo foo; int bar = 2; int x = PREPRO_MIN(foo, bar); return 0; }
Wäre es ein Template bekämst du eine aussagekräftige Fehlermelsung.
Aber ohne Template bekomme ich auch eine aussagekräftige Fehlermeldung:
"Incompatible Type-Conversation" in der Zeileint x = PREPRO_MIN(foo, bar);
Ich verstehe den Unterschied nicht ganz. Ich meine so oder so bekomme ich eine Fehlermeldung vom Compiler geliefert!
Da der Compiler doch vor dem Kompilieren den Preprocessor startet, müsste der Compiler danach doch überprüfen können, ob die Typen stimmen.
thx
-
Natuerlich findet eine Typenpruefung statt - schliesslich macht der Praeprozessor nur eine Textersetzung -> aber exakt diese Textersetzung macht nur die Ersetzung und checkt weder Tzpen noch sonstwas.
-
Shade Of Mine schrieb:
Natuerlich findet eine Typenpruefung statt - schliesslich macht der Praeprozessor nur eine Textersetzung -> aber exakt diese Textersetzung macht nur die Ersetzung und checkt weder Tzpen noch sonstwas.
Genau das wollte ich auch wissen. Also der Preprocessor macht keine Typprüfung, das Resultat vom Preprocessor bekommt der Compiler natürlich zu Gesicht und führt eine Typprüfung durch.
Es gibt für den Compiler keine Möglichkeit, zu überprüfen, ob die Makroparameter kompatible Typen haben. Das Makro wird ohne besondere Typprüfung erweitert.
Aber beim Kompilieren wird der Fehler entdeckt.
Wenn das, was ich hier aufgeschrieben habe, richtig ist, dann ist das Thema geklärt.
thx Jungs