Makro funktioniert nicht, warum?
-
Danke für deine Antwort.
Aber, hm , ich sehe den Fehler, bis auf das fehlende Semikolon nach atemp und die Zählweise in der Schleife, noch nicht.
Warum würde dein Aufruf nicht funktionieren?
MfG
-
jizzer schrieb:
Aber, hm , ich sehe den Fehler, bis auf das fehlende Semikolon nach atemp und die Zählweise in der Schleife, noch nicht.
Warum würde dein Aufruf nicht funktionieren?
Das hier:
int main(int argc, char* argv[]) { double x = {double 3.141, atemp; int 4; atempt = 3.141 for(;4>=0;4--){3.141*=atemp}}; }
Ist kein gültiger C Quelltext. Aber genau das tippst du ein, wenn du
int main(int argc, char* argv[]) { double x = pow(3.141, 4); }
eintippst.
Genau genommen nicht mal das, weil Makro-Parameter keine Typen haben...
Makros sind Text-Ersetzungen. Der Präprozessor weiß eigentlich garnichts über C.
-
außerdem darf man bei Makros mit Parametern diese nicht mit Typen deklarieren. Vielleicht ist das einer der Fehlermeldungen.
-
Ok, danke euch. Gibt es dann eine Möglichkeit, x^y mit einem Makro zu realisieren?
MfG
-
jizzer schrieb:
Ok, danke euch. Gibt es dann eine Möglichkeit, x^y mit einem Makro zu realisieren?
Klar:
#include <math.h> #define macro(base, exponent) (pow(base, exponent))
Fürs Selberbauen (nur für Integer-Exponenten?) bietet sich eine Funktion eher an, typischerweise ohne Einbussen, weil sie wahrscheinlich inlined werden kann. Das billige Makrosystem von C hat Probleme mit lokalen Variablen, weil man nie sicher sein kann, dass deren Namen noch nicht in Gebrauch sind.
-
wieso bist du auf Makros deart fixiert? Makros haben den großen Nachteil, dass sie nicht Typsicher sind und undefiniertes Verhalten hervorrufen können, was sehr schwer zu debuggen ist. Für die Potenz solltest entweder eine Funktion selber schreiben, oder man: pow aus
math.h
verwenden.
-
supertux schrieb:
Makros haben den großen Nachteil, dass sie nicht Typsicher sind und undefiniertes Verhalten hervorrufen können, was sehr schwer zu debuggen ist.
Hmm, Funktionen können nichts Undefiniertes "hervorrufen"?
-
Ganz kurz: Makros sind Scheisse!
-
abc.w schrieb:
Ganz kurz: Makros sind Scheisse!
Klar. Und ein Hammer auch, sobald du deinen Daumen getroffen hast?
-
Es ist mit Makros sehr viel leichter, Unfug zu machen, weil sie sich nicht an die üblichen Lookup-Regeln halten - Scopes interessieren sie nicht. Unter Windows machen beispielsweise die Makros "min" und "max" aus <windows.h> regelmäßig Probleme.
Zwar ist diese Problematik in C++ gravierender als in C, nichtsdestoweniger empfiehlt sich im Umgang mit Makros große Vorsicht. Sie können unerwünschte Nebeneffekte auf bestehenden Code haben, und diese können wenig offensichtlich und dementsprechend schwer zu beheben sein.
-
seldon schrieb:
Unter Windows machen beispielsweise die Makros "min" und "max" aus <windows.h> regelmäßig Probleme.
Wie sind die definiert?
-
mngbd schrieb:
seldon schrieb:
Unter Windows machen beispielsweise die Makros "min" und "max" aus <windows.h> regelmäßig Probleme.
Wie sind die definiert?
#ifndef NOMINMAX #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif #endif /* NOMINMAX */
-
Und die machen Probleme mit Scopes?
-
mngbd schrieb:
Klar:
#include <math.h> #define macro(base, exponent) (pow(base, exponent))
Na toll, damit schreibe ich die Funktion aber nicht selbst, sondern benenne eine in math.h vorhandene um.
Sonst noch vorschläge ?
-
jizzer schrieb:
Sonst noch vorschläge ?
Für beliebige Exponenten sind mir keine problemlosen bekannt. Aber wenn du uns sagst, wofür du das brauchst, können wir vielleicht eines konstruieren, das zumindest die Probleme vermeidet, die du nicht haben willst.
Editgrammatik
-
Natürlich machen die Probleme mit Scopes. Der häufigste Zusammenhang ist in C++ mit numeric_limits, etwa
#include <limits> #include <windows.h> // ... double d = std::numeric_limits<double>::max(); // KAWUMM!
aber in reinem C kann einem sowas beispielsweise mit Funktionszeigern leicht auseinanderfliegen. Nimm an, ich modelliere ein Objektsystem in C und habe darin etwa folgendes:
struct collection { void *max(collection *self, int (*compare)(void*, void*)); }; int compare_int(void *p, void *q) { return *(int*)p < *(int*)q; } /* ... */ collection c; /* Fülle collection */ int x = *(int*)c.max(&c, int_compare);
Da definiere mal so ein max vor und sag mir, ob du die Fehlermeldungen noch verstehst.
Was diesen Use-Case angeht, es macht keinen Sinn, das mit Makros zu versuchen. Es mag in manchen Compilern Erweiterungen geben, die so etwas ermöglichen, aber da sich das ganze mit einer Funktion lösen lässt, besteht wirklich keinerlei Grund, auf Makros zurückzugreifen - mit einer Funktion hast du all diese Probleme nicht, und du kannst Dinge damit machen, die mit einem Makro nicht gehen (es gibt beispielsweise keine Zeiger auf Makros).
-
Dann halt nich. dann muss ich mich wohl mit bestimmten fällen wie x² oder x³ zufrieden geben. wobei.. könnte man bspw.folgendes
#define pow(x) (x) * (x)
.
.
.
pow(pow(x));tun, also Makros verschachteln?
-
abc.w schrieb:
Ganz kurz: Makros sind Scheisse!
Nein, das sind sie auch nicht. Manchmal ersapren Makros verdammt viel getippe:
Z.b. in einer Bibliothek habe ich (Makros und Inhalt weitgehend geändert)
#define get_value_typed(type, type_short_name, c_type)\ int get_obj_ ##type_short_name(data_obj *cv, c_type *val)\ {\ int ret;\ if(cv == NULL || val == NULL)\ return 0;\ if ((cv->dtype != TYPE_INVALID) && (cv->dtype != type)) return 0;\ ret = obj_request(cv, cv->read_to);\ if(ret == 0)\ return 0;\ *val = (c_type) obj_get_value(cv);\ return 1; } get_value_typed(TYPE_I8, i8, int8_t); get_value_typed(TYPE_U8, u8, uint8_t); get_value_typed(TYPE_I16, i16, int16_t); get_value_typed(TYPE_U16, u16, uint16_t); get_value_typed(TYPE_I32, i32, int32_t); get_value_typed(TYPE_U32, u32, uint32_t);
Damit hab ich sofort die Implementierung für Funktionen:
int get_obj_i8(data_obj *cv, int8_t); int get_obj_u8(data_obj *cv, uint8_t); ....
mngbd schrieb:
supertux schrieb:
Makros haben den großen Nachteil, dass sie nicht Typsicher sind und undefiniertes Verhalten hervorrufen können, was sehr schwer zu debuggen ist.
Hmm, Funktionen können nichts Undefiniertes "hervorrufen"?
ja, das stimmt. Was ich aber sagen wollte, dass man mit Makros viel leichter nicht offensichtliche Fehler machen kann.
-
Der Typ hier verwendet pow als Makro. Aber wenn ich das ausführen will gehts nicht.
http://c-buch.sommergut.de/Kapitel12/Symbolische-Konstanten-und-Makros.shtml
-
Er erläutert im umgebenden Text aber auch, warum das keine gute Idee ist.