#define für Text ?

AckiB

Mitglied
Hallo,
ich habe da ein Problem, dass eigentlich kein Problem sein dürfte... ;)
Ich habe am Anfang der Datei ein #define für die Stringlänge.
Das funktioniert auch wie erwachtet, bis auf eine Ausnahme:

Code:
#define MAXSTRING 256

void loadData(){
  char iniFile[MAXSTRING]; // wird wie erwartet erstetzt
  cIniEd tmp;

  strcpy(iniFile, projekt_Daten.projekt_Pfad);
  strcat(iniFile, "MAXSTRING.ini"); // wird nicht erstetzt
  tmp.setPfad(iniFile);

}

Ich erhalte immer den Dateinahmen "MAXSTRING.ini", der sollte aber doch jetzt "256.ini" sein, oder ?

CU, Acki
 
Versuch es mal so:
Code:
#define MAXSTRING "256"
strcat(iniFile, MAXSTRING ".ini"); // wird nicht erstetzt
Eine andere Lösung kenne ich nicht, ausser Umwandlungsfunktionen (Z.B. sprintf()) oder Ausgabestreams zu verwenden.
Beispiel:

Code:
#define MAXSTRING (256)

...

  char buffer[40];
  sprintf( buffer, "%d.ini", MAXSTRING );
  printf( buffer );
  strcat(iniFile, buffer ".ini");
Übrigens könntest du die Zeile mit dem #define besser durch folgende ersetzen:
Code:
const int MAXSTRING = 256;
 
@Kachelator: Wieso sollte man ein #define deiner Ansicht nach durch ein const ersetzen? Dieser Grundsatz ist mir völlig neu!

Gawayn
 
Nach Möglichkeit sollte man auf Defines ganz verzichten, wenn man stattdessen typsichere Definitionen verwenden kann. Im Unterschied zu #Defines, die im Quelltext ersetzt werden, bevor der Compiler sie zu Gesicht bekommt, geht beispielsweise das "const int " so an den Compiler weitergegeben. Das kann sehr hilfreich bei der Fehlervermeidung sein. Ebenso halte ich es für sinnvoll, wo es geht, Funktionstemplates anstelle von Define-Makros zu verwenden. Das setzt natürlich C++ voraus.

Eine beliebte Falle stellt zum Beispiel das Makro max() aus der windef.h dar:
Code:
#define max(a,b)            (((a) > (b)) ? (a) : (b))
Das Problem ist, das a und b je nach ihrem Wert hier ein oder zwei mal ausgewertet werden, ohne dass das im Code offensichtlich wäre. Was passiert nämlich, wenn a zum Beispiel ein Ausdruck der Form ++i ist...?
Ich glaube, zu der Thematik findet man im Netz reichlich Material. Hier zum Beispiel:
Makros:
Makros sind in C sehr wichtig.
#define SQUARE(a) a*a
int x = 5;
int y = SQUARE (x+2); /* berechnet wird: y = x + (2*x) + 2 */

Brjane Stroustroup äussert sich in seinem berühmten Buch "Die C++ Programmiersprache" wie folgt:
"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."
"
(Quelle: http://www.wackerart.de/c.html )
 
Zuletzt bearbeitet:
Ja, dieser Problematik bin ich mir bewusst. Ich setze Defines ausschließlich für Konstante ein. Auf solche Scherze wie max( ++a, b ) verzichte ich ohnehin -- ich denke, wer soetwas schreibt, schreit nach Fehlern. Mitdenken ist angesagt. Defines haben halt den großen Vorteil, effizienteren Code zu erzeugen, da ja ein ganzer Speicherzugriff entfällt. Die Zahl, auf die es ankommt, ist bereits im Mnemonic kodiert und muss nicht noch von einer anderen Adresse geladen werden.

Gawayn
 
Mitdenken ist angesagt. Defines haben halt den großen Vorteil, effizienteren Code zu erzeugen, da ja ein ganzer Speicherzugriff entfällt. Die Zahl, auf die es ankommt, ist bereits im Mnemonic kodiert und muss nicht noch von einer anderen Adresse geladen werden.
Sicher? Ich habe mich allerdings mit der Problematik in den letzten Jahren nicht mehr so sehr beschäftigt, da ich der Meinung bin, dass aktuelle Compiler durchaus in der Lage sind, auf dieser Ebene Code effizienter zu optimieren als ein menschlicher Programmierer.
 
Es gibt die Möglichkeit, zumindest in Visual Studio, mit

#define MAXSTRING 256
#define ALSSTRING( x ) printf( #x "\n" )

Man beachte das # innerhalb des Makros. Dadurch wird ein Makro als Text eingesetzt.

Zu anderweitigen Problemen mit Defines ist hier ja schon genug gesagt worden.

Eine andere möglichkeit wären noch enums. Ich erzeuge zum Beispiel Konstanten einer Klasse generell als Member-Enums. Der Default-Namespace bleibt sauber, und Intellisense zeigt mir alle Konstanten an.
 
Original geschrieben von Endurion

#define MAXSTRING 256
#define ALSSTRING( x ) printf( #x "\n" )
Das printet "MAXSTRING" und nicht "256". #x gibt das Token aus, nicht den Wert desselben. Eignet sich gut, um zu Debugzwecken Variablen zu dumpen, aber nicht, um aus einer Zahl einen String zu machen.
 
Hoppla, hab mal wieder zuviel Gutes angenommen.

Stimmt, funktioniert nicht.

Mea culpa grande maxima. Oder so.

Benutz enums - beschwöööööör - enuuuuuuums.


And now to something completely different...
 
Zurück