JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=b7203fe5683ce360d39b75219f3ef0eeMedaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Defines, Makros, etc.
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Otscho
Super JLI'ler


Alter: 35
Anmeldedatum: 31.08.2006
Beiträge: 338
Wohnort: Gummibären-Gasse
Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 18:02    Titel: Antworten mit Zitat

DirectXer hat Folgendes geschrieben:

und gleichzeitig ein weiterer gravierender Grund, keine #defines zu benutzen, wenn man sieht wie aufwendig die Fehlersuche war! Razz

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
manu
Super JLI'ler


Alter: 34
Anmeldedatum: 09.03.2006
Beiträge: 327
Wohnort: allgäu (DE)
Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 18:25    Titel: Antworten mit Zitat

ich hätte anstatt den defines eher zu

CPP:
const int GAME_STATE = 20;

,oder wie auch immer, tendiert.... Wink
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 18:40    Titel: Antworten mit Zitat

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! Razz

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:

Arrow die sympolsichen Namen der #defines werden vom Compiler nicht erkannt und deshalb auch nicht in Fehlermeldungen berücksichtigt
Arrow der Präprozessor nimmt in #defines schlichte code ersetzungen durch, und überprüft daher nicht auf fehler in der syntax
Arrow #defines die als Funktionsersatz gelten sollen ziehen nicht den erwarteten Overhead nach sich (s.u.)
Arrow #defines sind nicht typsicher ( Exclamation )
Arrow 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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Jonathan_Klein
Living Legend


Alter: 36
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 18:48    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 18:54    Titel: Antworten mit Zitat

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 Razz

@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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Otscho
Super JLI'ler


Alter: 35
Anmeldedatum: 31.08.2006
Beiträge: 338
Wohnort: Gummibären-Gasse
Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 19:36    Titel: Antworten mit Zitat

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) Laughing
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
GreveN
JLI Master


Alter: 37
Anmeldedatum: 08.01.2004
Beiträge: 901
Wohnort: Sachsen - Dresden
Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 19:42    Titel: Antworten mit Zitat

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! Razz

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
Benutzer-Profile anzeigen Private Nachricht senden Yahoo Messenger MSN Messenger
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 20:16    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
David
Super JLI'ler


Alter: 39
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 20:40    Titel: Antworten mit Zitat

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! Wink 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
Benutzer-Profile anzeigen Private Nachricht senden
Otscho
Super JLI'ler


Alter: 35
Anmeldedatum: 31.08.2006
Beiträge: 338
Wohnort: Gummibären-Gasse
Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 20:47    Titel: Antworten mit Zitat

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. Rolling Eyes
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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
David
Super JLI'ler


Alter: 39
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 20:54    Titel: Antworten mit Zitat

Nich Macros mit Präprozessordirektiven verwechseln bitte! Razz

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. Smile
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Hazel
JLI MVP
JLI MVP


Alter: 39
Anmeldedatum: 19.07.2002
Beiträge: 1761

Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 21:01    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 19.05.2007, 22:09    Titel: Antworten mit Zitat

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. Smile

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
foreach
ehem. hanse



Anmeldedatum: 08.05.2004
Beiträge: 183

Medaillen: Keine

BeitragVerfasst am: 20.05.2007, 15:15    Titel: Antworten mit Zitat

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
Code:
#pragma once
Directive?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
GreveN
JLI Master


Alter: 37
Anmeldedatum: 08.01.2004
Beiträge: 901
Wohnort: Sachsen - Dresden
Medaillen: Keine

BeitragVerfasst am: 20.05.2007, 15:19    Titel: Antworten mit Zitat

Nicht standardisiert und damit nicht klar definiert bzw. überall unterstützt.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Yahoo Messenger MSN Messenger
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
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

Impressum