www.mikrocontroller.net

Forum: GCC #define als String "umdefinieren"


Autor: Dirk (Gast)
Datum:

Hallo!

Ich würde gerne wissen, ob es eine Möglichkeit gibt, ein define auf zwei
Arten zu benutzen:

#define ZAHL 123

Das brauche ich irgendwo im Code in folgender Form:

int n = ZAHL;
bla...

Aber ich möchte auch einen String (im ROM) damit initialisiert haben:

char ROMCONST asN[3] = "123";

So funktioniert´s nicht, klar:

char ROMCONST asN[3] = "ZAHL";

Wie mach ich dem Compiler klar, daß er für ZAHL in den Hochkommas "123"
(als String!) einsetzen soll?
Gibt´s da ne Möglichkeit?

Gruß, Dirk.
Autor: Karl Heinz Buchegger (kbuchegg) (Moderator)
Datum:

Dirk wrote:
> Gibt´s da ne Möglichkeit?

Ja gibt es.
Du brauchst dazu das 'Stringize' #-Token des Präprozessors.
#define STR(x)   #x
#define XSTR(x)  STR(x)

#define TEST   17

int main()
{
  printf( "%s", XSTR(TEST) );
}

Der Umweg über ein Zwischenmakro ist notwendig, damit die
Makroauswertung korrekt abläuft.
Autor: Johannes M. (johnny-m)
Datum:

Verstehe noch nicht ganz, was Du wirklich willst, aber von den beiden
Varianten...
> char ROMCONST asN[3] = "123";
>
> So funktioniert´s nicht, klar:
>
> char ROMCONST asN[3] = "ZAHL";
funktioniert keine . "123" sind in C 4 Zeichen, und die passen nicht
in ein Array mit 3 Elementen rein, von "ZAHL" (5 Zeichen) mal ganz zu
schweigen. Meist ist es überflüssig, bei einem Array, das explizit
initialisiert wird, die Breite anzugeben.

Aber wenn ich das korrekt verstehe, dann macht die erste Variante (wenn
Du die 3 in den eckigen Klammern weglässt) genau das, was Du willst.
Nach
char asN[] = "123";
steht in asN[0] eine '1' (0x31), in asN[1] eine '2' (0x32), in asN[2]
eine '3' (0x33) und in asN[3] eine '\0' (0x00).

EDIT:
Oder wolltest Du doch was anderes? Wenn ja, dann liegt Karl Heinz
möglicherweise richtig...

NOCH EIN EDIT:
Ich glaub, so langsam fällt der Groschen... Aber wie gesagt und
unabhängig davon: Achte auf den Nullterminator!
Autor: Dirk (Gast)
Datum:

Vielen Dank euch beiden.

Genau das, was Karl Heinz erläutert hat, hab ich gesucht...
Ich hab den Operator zwar schon gefunden gehabt
(http://www.tfh-berlin.de/~kempfer/skript_c/Kap12.html), aber ich bin
natürlich nicht auf die Idee gekommen, das nochmal zu "makrofizieren" ;)

@Johannes: Ja, sorry, das hätte ich sagen sollen: Die Nullterminierung
will/brauch ich eben nicht, weil ich noch eine zweite Konstante habe,
die den Platz im Array entsprechend reserviert (wird noch anderswo für
ein Objekt-Verzeichnis benötigt, deswegen kann ich das Array nicht
einfach "so" initialisieren...)


Gruß, Dirk.
Autor: Johannes M. (johnny-m)
Datum:

Dirk wrote:
> @Johannes: Ja, sorry, das hätte ich sagen sollen: Die Nullterminierung
> will/brauch ich eben nicht, weil ich noch eine zweite Konstante habe,
> die den Platz im Array entsprechend reserviert (wird noch anderswo für
> ein Objekt-Verzeichnis benötigt, deswegen kann ich das Array nicht
> einfach "so" initialisieren...)
Ob Du die brauchst oder nicht, denk daran, dass ein Ausdruck in "" immer
nullterminiert ist, und dass der Ausdruck auch in den Speicher
geschrieben wird, ohne Rücksicht auf Verluste. Wenn hinter dem letzten
'reservierten' Array-Element schon was anderes steht, dann Peng ...
Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Johannes M. wrote:

> Ob Du die brauchst oder nicht, denk daran, dass ein Ausdruck in "" immer
> nullterminiert ist,

Jein.

> und dass der Ausdruck auch in den Speicher
> geschrieben wird, ohne Rücksicht auf Verluste.

Nein.

6.7.8 Initialization, Absatz 14:

“An array of character type may be initialized by a character string
literal, optionally enclosed in braces. Successive characters of the
character string literal (including the terminating null character if
there is room or if the array is of unknown size) initialize the
elements of the array.”

Man beachte das “if there is room”.
Autor: Johannes M. (johnny-m)
Datum:

Jörg Wunsch wrote:
> 6.7.8 Initialization, Absatz 14:
>
> “An array of character type may be initialized by a character string
> literal, optionally enclosed in braces. Successive characters of the
> character string literal (including the terminating null character if
> there is room or if the array is of unknown size) initialize the
> elements of the array.”
>
> Man beachte das “if there is room”.
Hmmm, bei der Initialisierung kann also tatsächlich nix kollidieren?
Bedeutet also, dass, wenn die Array-Größe explizit angegeben wird, diese
Angabe (zumindest bei einer Initialisierung) das mächtigere Argument
ist? OK, und bei der Initialisierung besteht auch noch die Möglichkeit,
sich den Speicher nach Bedarf zurechtzubiegen, da Compiler und Co. ja
sehen, was da passiert...

Aber gilt das nur für den Nullterminator? Wenn andere Zeichen über die
Array-Grenzen hinaus geschrieben werden sollen, müsste es ja mindestens
ne Warnung geben.
Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Johannes M. wrote:

> Hmmm, bei der Initialisierung kann also tatsächlich nix kollidieren?

Ja, schließlich hat der Compiler ja eine explizite Anweisung dazu
erhalten, wie groß das Array werden soll.

> Aber gilt das nur für den Nullterminator?

Mehr ist zumindest erstmal vom Standard nicht abgedeckt.

> Wenn andere Zeichen über die
> Array-Grenzen hinaus geschrieben werden sollen, müsste es ja mindestens
> ne Warnung geben.

Würde ich auch erwarten.  Test:
% cat foo.c
char foo[4] = "Hello";
% cc -Os -Wall -Wextra -c foo.c
foo.c:1: warning: initializer-string for array of chars is too long
Autor: Johannes M. (johnny-m)
Datum:

@ Jörg Wunsch:
Aha. Danke vielmals. Wieder was gelernt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net