 |
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Otscho Super JLI'ler

Alter: 36 Anmeldedatum: 31.08.2006 Beiträge: 338 Wohnort: Gummibären-Gasse Medaillen: Keine
|
Verfasst am: 19.05.2007, 18:02 Titel: |
|
|
DirectXer hat Folgendes geschrieben: |
und gleichzeitig ein weiterer gravierender Grund, keine #defines zu benutzen, wenn man sieht wie aufwendig die Fehlersuche war!
Gruß DXer |
#defines zu benutzen ist die beste Möglichkeit einen aufgeräumten Code zu schreiben und erschweren die Fehlersuche eher selten, wenn man sie schön geordnet und kommentiert am Anfang hinschreibt. (siehe Snowsong).
Mich würde interessieren, wie du sowas gemacht hättest. |
|
Nach oben |
|
 |
manu Super JLI'ler

Alter: 35 Anmeldedatum: 09.03.2006 Beiträge: 327 Wohnort: allgäu (DE) Medaillen: Keine
|
Verfasst am: 19.05.2007, 18:25 Titel: |
|
|
ich hätte anstatt den defines eher zu
CPP: | const int GAME_STATE = 20; |
,oder wie auch immer, tendiert....  |
|
Nach oben |
|
 |
DirectXer Dark JLI'ler

Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 19.05.2007, 18:40 Titel: |
|
|
Otscho hat Folgendes geschrieben: | DirectXer hat Folgendes geschrieben: |
und gleichzeitig ein weiterer gravierender Grund, keine #defines zu benutzen, wenn man sieht wie aufwendig die Fehlersuche war!
Gruß DXer |
#defines zu benutzen ist die beste Möglichkeit einen aufgeräumten Code zu schreiben und erschweren die Fehlersuche eher selten, wenn man sie schön geordnet und kommentiert am Anfang hinschreibt. (siehe Snowsong).
Mich würde interessieren, wie du sowas gemacht hättest. |
ich hätte es in C++ gemacht: CPP: | enum
{
GAME_INIT,
GAME_RE_INIT,
GAME_PRE_MENU,
GAME_MENU
//usw.
} | es mag sein, #defines sind eine möglichkeit, aufgeräumten Code zu schreiben, aber keinen C++-Code. #defines sind nicht Element der Sprache C++ und laut ISO C++ standard in keinem C++-Compiler vorausgesetzt, da sie eh zu Präprozessoranweisungen gehören. Es gibt für alle Einsatzmöglichkeiten von #defines, die dem C++Part des Codes dienen, eine sauberere, schönere, anerkannte, portable und leichtere Alternative in C++ (siehe enums, templates, consts, inlines...; generell war dies ein Konzept der entwiclung c -> c++). Es hat schon ziemlich viele Diskusionen auf diesem Board hier gegeben, die sich mit genau demselben Thema befasst haben. Ich möchte jetzt auch nicht eine weitere Diskussion in diesem Thread, der dafür eigentlich nicht vorgesehen war, starten. Wenn du trotzdem darüber diskutieren willst, bitte ich dich mir entweder eine PM zu schreiben, oder einen neuen Thread zu eröffnen. Deshalb zähle ich nur mal die stichhaltigsten Argumente und 2 kleine Beispiele auf:
die sympolsichen Namen der #defines werden vom Compiler nicht erkannt und deshalb auch nicht in Fehlermeldungen berücksichtigt
der Präprozessor nimmt in #defines schlichte code ersetzungen durch, und überprüft daher nicht auf fehler in der syntax
#defines die als Funktionsersatz gelten sollen ziehen nicht den erwarteten Overhead nach sich (s.u.)
#defines sind nicht typsicher ( )
Brjane Stroustroup (der C++-Guru) äussert sich in seinem berühmten Buch "Die C++ Programmiersprache" wie folgt:
Zitat: | Fast jedes Makro demonstriert eine Schwäche in der Programmiersprache, im Programm oder beim Programmierer. Da Makros den Programmtext ändern, bevor der Compiler ihn richtig liest, sind Makros außerdem ein großes Problem für viele Programmierwerkzeuge. Wenn man also Makros benutzt, muß man schlechtere Dienste von Werkzeugen wie Debuggern, Crossreferenz-Werkzeugen und Profilern erwarten. |
berühmtestes Beispiel: CPP: | #define max(a,b) (a) > (b) ? (a) : (b)
// unten im code
int a = 2;
int b = 4;
int c = max( ++a ,b ); | hier ergibt die ersetzung: CPP: | int c = (++a) > (b) ? (++a) : (b); | a wird fälschlicherweise 2 mal inkrementiert. Potentielle Lösung in C++: CPP: | template<typename T>
inline T max(T a, T b)
{
return a > b ? a : b;
} |
Beispiel2: CPP: | #define SQUARE(a) a*a
// unten im Code
int x = 5;
int y = SQUARE (x+2); | das ergibt: CPP: | int y = x+2*x+2 // siehe Punkt vor Strich |
Trotzdem gibt es auch einige wenige Fälle in denen #defines möglich und anerkannt sind, wenn man sie richtig einsetzt; nur sind diese Fälle durch den Schritt c -> c++ stark eingeschränkt. Zwei solcher Fälle sind zum Beispiel der string-literal-preprocessor-operator # und die include-guards.
Gruß DXer |
|
Nach oben |
|
 |
Jonathan_Klein Living Legend

Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 19.05.2007, 18:48 Titel: |
|
|
Nicht zu vergessen: Die __LINE__ und __FILE__ Anweisungen. Imho geht das NUR mit #defines. Ist enorm praktisch, wenn man ein Logbuch schreiben will. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
 |
DirectXer Dark JLI'ler

Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 19.05.2007, 18:54 Titel: |
|
|
Jonathan_Klein hat Folgendes geschrieben: | Nicht zu vergessen: Die __LINE__ und __FILE__ Anweisungen. Imho geht das NUR mit #defines. Ist enorm praktisch, wenn man ein Logbuch schreiben will. |
nein, das geht auch ohne, da dies predefined macros sind, die durch den Präprozessor generell ersetzt werden. Habs grad nochmal bei VC++ 2005 ausprobiert
@Mod Es wäre vllt doch sinnvoll, diesen Teil mal in einem extra Thread abzuspalten, da das doch ein wichtiges Thema ist, und AFAIK bis jetzt nur als Nebenthema behandelt wurde.
Gruß DXer |
|
Nach oben |
|
 |
Otscho Super JLI'ler

Alter: 36 Anmeldedatum: 31.08.2006 Beiträge: 338 Wohnort: Gummibären-Gasse Medaillen: Keine
|
Verfasst am: 19.05.2007, 19:36 Titel: |
|
|
Ich wär auch für einen neuen Thread.
DirextXer kennt sich mit Makros ja recht gut aus. Die könnt er(oder naürlich auch jemand anderer) mal in einem Tut oder sowas vorstellen. (Die wichtigsten zumindest)  |
|
Nach oben |
|
 |
GreveN JLI Master

Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 19.05.2007, 19:42 Titel: |
|
|
DirectXer hat Folgendes geschrieben: | Otscho hat Folgendes geschrieben: | DirectXer hat Folgendes geschrieben: |
und gleichzeitig ein weiterer gravierender Grund, keine #defines zu benutzen, wenn man sieht wie aufwendig die Fehlersuche war!
Gruß DXer |
#defines zu benutzen ist die beste Möglichkeit einen aufgeräumten Code zu schreiben und erschweren die Fehlersuche eher selten, wenn man sie schön geordnet und kommentiert am Anfang hinschreibt. (siehe Snowsong).
Mich würde interessieren, wie du sowas gemacht hättest. |
ich hätte es in C++ gemacht: CPP: | enum
{
GAME_INIT,
GAME_RE_INIT,
GAME_PRE_MENU,
GAME_MENU
//usw.
} | es mag sein, #defines sind eine möglichkeit, aufgeräumten Code zu schreiben, aber keinen C++-Code. #defines sind nicht Element der Sprache C++ und laut ISO C++ standard in keinem C++-Compiler vorausgesetzt, da sie eh zu Präprozessoranweisungen gehören. Es gibt für alle Einsatzmöglichkeiten von #defines, die dem C++Part des Codes dienen, eine sauberere, schönere, anerkannte, portable und leichtere Alternative in C++ (siehe enums, templates, consts, inlines...; generell war dies ein Konzept der entwiclung c -> c++). |
Inclusion Guards sind auch ein Thema bei welchem ich nicht auf Makros verzichten wöllte. Prinzipiell gebe ich dir recht, aber manchmal sind sie auch einfach ungemein nützlich, gerade weil Templates in Verbindung mit 'typedef' manchmal noch so einige Zicken machen, kann man sich unter Umständen viel lästige Tipparbeit ersparen, aus welcher unschöner und unleserlicher Code und somit eine erhöhte Fehleranfälligkeit resultiert. Bestes Beispiel welches mir gerade einfällt sind die Typlisten, welche Alexandrescu in seinem Buch "Modern C++-Design" vorstellt.
Ein 'enum'-Fan bin ich aber prinzipiell auch nicht, weil mir das Konstrukt i.d.R. zu statisch ist, da gibt's meistens schönere Ansätze, gerade wenn es um Gamestates geht - Bsp.: State Pattern. |
|
Nach oben |
|
 |
DirectXer Dark JLI'ler

Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 19.05.2007, 20:16 Titel: |
|
|
naja, das mit den enums ist eben Geschmackssache. Hauptsache, es gehört elementar zur Sprache C++.
Zu der anderen Sache, GreveN: es stimmt schon, in manchen Fällen gibt es wirklich gerechtfertigte und anerkannte Einsatzmöglichkeiten für defines, wie ich oben schon geschrieben hab. Man kann sie auch wunderbar mit templates und der generischen Programmierung verbinden, wie das z.B. in boost gemacht wird: Boost hat Folgendes geschrieben: | CPP: | template<
typename FunctionObj,
typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS
>
struct BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER
{
typedef typename ct_if<(is_void<R>::value),
BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER<
FunctionObj,
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>,
BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER<
FunctionObj,
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>
>::type type;
}; |
| (alle groß geschriebenen Wörter sind defines)
@Otscho: An welche Art von Makros denkst du denn z.B.?
Gruß DXer |
|
Nach oben |
|
 |
David Super JLI'ler
Alter: 40 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 19.05.2007, 20:40 Titel: |
|
|
Wenn der Präprozessor richtig genutzt wird ist das ein tolles Mittel. Wie DirectXer gerade angeprochen hat ist "preprocessor metaprogramming" eine tolle Sache um ultra flexiblen Code zu erzeugen! Siehe das Functor Template von boost!
Dann ist Macros klasse um Tiparbeit zu sparen und den Code übersichtlicher zu machen.
Aber Macros haben auch viele Probleme, die ja oben schon angesprochen sind. So sollten sie nicht als Typersatz oder Funktionsersatz verwendet werden.
grüße |
|
Nach oben |
|
 |
Otscho Super JLI'ler

Alter: 36 Anmeldedatum: 31.08.2006 Beiträge: 338 Wohnort: Gummibären-Gasse Medaillen: Keine
|
Verfasst am: 19.05.2007, 20:47 Titel: |
|
|
Ich denk da an keine Bestimmte. Ein kleiner Überblick über die Gängigsten wär vielleich ganz net und hilfreich. Viele kennen wahrscheinlich nur #define und #include.
In Wikipedia steht folgendes: Zitat: | Ein Makro in der Programmierung ist ein kleines Stück Programmcode, das von einem Interpreter oder Präprozessor durch ein größeres Stück Programmcode ersetzt wird. Damit ist es möglich, oft wiederkehrende Programmstrukturen durch Kürzel zu vereinfachen oder literale Konstanten durch semantische Bezeichnungen zu ersetzen. |
|
|
Nach oben |
|
 |
David Super JLI'ler
Alter: 40 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 19.05.2007, 20:54 Titel: |
|
|
Nich Macros mit Präprozessordirektiven verwechseln bitte!
DirectXer hat Folgendes geschrieben: |
nein, das geht auch ohne, da dies predefined macros sind, die durch den Präprozessor generell ersetzt werden. Habs grad nochmal bei VC++ 2005 ausprobiert Razz
|
Wie meinst du das? Natürlich geht das, nur ist in dem Fall evtl das Ergebniss total verfälscht.  |
|
Nach oben |
|
 |
Hazel JLI MVP


Alter: 40 Anmeldedatum: 19.07.2002 Beiträge: 1761
Medaillen: Keine
|
Verfasst am: 19.05.2007, 21:01 Titel: |
|
|
Otscho hat Folgendes geschrieben: | #defines zu benutzen ist die beste Möglichkeit einen aufgeräumten Code zu schreiben [...] |
Das halte ich für ein Gerücht. Nach all den Jahren sind die Programmiersprachen endlich soweit, dass die beste Möglichkeit einen aufgeräumten Code zu schreiben die Module sind. ;-P _________________ *click* Dabuu!?
Twitter: http://twitter.com/Ollie_R
|
|
Nach oben |
|
 |
DirectXer Dark JLI'ler

Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 19.05.2007, 22:09 Titel: |
|
|
David hat Folgendes geschrieben: | DirectXer hat Folgendes geschrieben: |
nein, das geht auch ohne, da dies predefined macros sind, die durch den Präprozessor generell ersetzt werden. Habs grad nochmal bei VC++ 2005 ausprobiert Razz
|
Wie meinst du das? Natürlich geht das, nur ist in dem Fall evtl das Ergebniss total verfälscht.  |
ja, da hast du Recht. Also, wenn man auf der sicheren Seite sein will, sollte man diese in #defines unterbringen.
@Otscho: Also wenn du Makros (entspr. #defines) meinst, dann eben die, die schon genannt wurden. z.B. für Unicode
CPP: | #ifdef UNICODE
#define TEXT(t) L##t
#else
#define TEXT(t) t
#endif | Dieses Konstrukt steht in der WinNT.h (über Windows.h) und dient dann dazu, bei Unicode dem String ein L voranzustellen
Wenn du allerdings Präprozessordirektive meinst, dann musst du nur mal einen Blick in die MSDN werfen, da stehen sie alle. Darunter ist z.B. die #pragma Direktive ein sehr weitläufiges Mittel um mit dem Präprozessor zu kommunizieren. Ich benutze z.B. sehr oft "#pragma region" und "#pragma endregion", um den Code bei Outlining zu verschönern.
Gruß DXer |
|
Nach oben |
|
 |
foreach ehem. hanse
Anmeldedatum: 08.05.2004 Beiträge: 183
Medaillen: Keine
|
Verfasst am: 20.05.2007, 15:15 Titel: |
|
|
DirectXer hat Folgendes geschrieben: | Trotzdem gibt es auch einige wenige Fälle in denen #defines möglich und anerkannt sind, wenn man sie richtig einsetzt; nur sind diese Fälle durch den Schritt c -> c++ stark eingeschränkt. Zwei solcher Fälle sind zum Beispiel [...] und die include-guards. |
was ist mit der Directive? |
|
Nach oben |
|
 |
GreveN JLI Master

Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 20.05.2007, 15:19 Titel: |
|
|
Nicht standardisiert und damit nicht klar definiert bzw. überall unterstützt. |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|