www.mikrocontroller.net

Forum: Compiler & IDEs Stringlänge mit Präprozessor-Direktive bestimmen


Autor: Thomas Finke (thomas-hn) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

gibt es beim GCC eine Möglichkeit, mit einer Präprozessor-Direktive die 
Stringlänge von einem mit #define definierten String zu bestimmen?

Also z.B.:

#define TESTSTRING "Dies ist der String"

und nun mit einer Präprozessor-Direktive die Länge von 19 Zeichen 
auslesen, so dass ich diese als festen Wert in dem C-Code verwenden 
kann.

Danke,

Thomas

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein #define macht garnicht, erzeugt keinen Code und belegt keinen SRAM.

Erst da, wo man es aufruft, passiert was.

Z.B. wenn man damit eine konstante Variable anlegt, kann man mit 
sizeof() deren Länge bestimmen (abschließende 0 zählt mit).


Peter

Autor: Hans-jürgen Herbert (hjherbert) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht im Präprozessor, aber im Compiler ist strlen() fest eingebaut und 
wird optimiert:

i = strlen( TESTSTRING ) ;
printf("Hello C-World.[%u] \n", i);

wird zu


  bc:  83 e1         ldi  r24, 0x13  ; 19
  be:  90 e0         ldi  r25, 0x00  ; 0
  c0:  9f 93         push  r25
  c2:  8f 93         push  r24
....

Autor: Thomas Finke (thomas-hn) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Hans-jürgen Herbert: Das ist genau das was gefehlt hat ;-)

Nun ist das Problem behoben.

Danke nochmals,

Thomas

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ansonsten würde auch gehen:

#define TESTSTRING_LENGTH (sizeof(TESTSTRING)-1)


Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
strlen() ist natürlich nur dann dem Compiler bekannt, wenn man

. Optimierungen aktiviert hat
. ihn im hosted mode (-fhosted) betreibt

Tja, da hammer das Dilemma wieder: eigentlich wäre ein Microcontroller
so'n schönes Paradebeispiel für eine freestanding application
(-ffreestanding), aber so richtig freestanding isses eben doch nicht
mehr, sowie man Teile der C-Standard-Bibliothek verwenden möchte.
Daher auch mein Argument, doch lieber in Kauf zu nehmen, dass man
sein main() mit dem Rückkehrtyp int deklariert, statt auf derartige
Vorteile zu verzichten (für eine hosted application gibt's zwei
genau vorgeschriebene Möglichkeiten, wie main() definiert werden
darf, bei freestanding verliert main() jegliche Sonderbedeutung gemäß
Standard).

Autor: (Gast) == (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wo kann man mehr über

Was_ist_das_überhaupt/Zweck/Anwendungsbeispiel/Arbeitsweise

von hosted mode und freestanding nachlesen? Bisher nutze ich mehr oder 
weniger Standard-makefiles und kümmer mich zu wenig bzw. weiß zu wenig 
um die Möglichkeiten der Build-Beeinflußung.

Danke,

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> für eine hosted application gibt's zwei genau vorgeschriebene
> Möglichkeiten, wie main() definiert werden darf

Da irrst du. Aus ISO/IEC9899:1999:
The function called at program startup is named main. The implementation
declares no prototype for this function. It shall be defined with a return
type of int and with no parameters:
          int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any
names may be used, as they are local to the function in which they are
declared):
          int main(int argc, char *argv[]) { /* ... */ }

or equivalent or in some other implementation-defined manner.

Der Compiler muß also die beiden genannten Varianten akzeptieren, darf 
aber auch beliebige andere unterstützen. Es ist nur festgelegt, daß die 
Name 'main' ist.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sehe ich anders. Es dreht sich um die Bedeutung von "shall" in "It 
shall be defined with a return type of int ..."

http://www.bartleby.com/61/37/S0313700.html schreibt dazu u.a. 
"Americans use shall to express an explicit obligation,..."

d.h. es besteht eine Verpflichtung eine der beiden Varianten zu 
benutzen.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe es als:

"It shall be defined A or B or C."

A = "with a return type of int and with no parameters"

B = "with two parameters..."

C = "in some other implementation-defined manner"

Ich sehe keinen Zwang, daß der Rückgabetyp 'int' auch für C gelten muß. 
Es könnte allerdings an einer mißverständlichen Formulierung liegen.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, was ich vergessen habe: Die Bedeutung von 'shall' innerhalb der 
C-Norm selbst ist explizit definiert und entspricht natürlich dem, was 
du geschrieben hast.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, die Formulierung ist recht verwaschen.  Ich denke, die zielt
darauf ab, dass man die historische Unix-Implementierung
int main(int argc, char **argv, char **environ);

nicht komplett verbieten wollte.  Müsste mal im rationale nachgucken
gehen.  Jetzt geh' ich aber erstmal Mittag essen. ;-)

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da sag mal einer Englisch ist eine eher einfache Sprache!

"It shall be defined with a return type of int (A) and with no parameters 
(B) or with two parameters (C) or equivalent (D) or in some other 
implementation-defined manner (E)."

Variante #1: A+B
Variante #2: A+C
...

Ich muss bekennen, dass die Varianten mit D und E über meinen Horizont 
gehen. Gibt es eine offizielle Übersetzung von ISO/IEC9899:1999? Müsste 
eigentlich, oder? Nee, anscheinend nicht.
http://www.iso.org/iso/en/CatalogueDetailPage.Cata...

Zu D gibt es in "meiner" Version (*) eine Fußnote 9)
"9) Thus, int can be replaced by a typedef name defined as int, or the 
type of argv can be written as char ** argv,and so on."

Daraus und daraus dass in "meiner" Version hinter dem "equivalent" noch 
ein Semikolon steht, sehe ich den D Fall als Spezialfall von A+C an

(*) WG14/N1124  Committee Draft — May 6, 2005 ISO/IEC 9899:TC2

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Daraus und daraus dass in "meiner" Version hinter dem "equivalent" noch
> ein Semikolon steht, sehe ich den D Fall als Spezialfall von A+C an

Bzw. auch als Spezialfall von A+B. Ich habe die Fußnote nur weggelassen, 
weil ich sie nicht als so wichtig angesehen hatte. Es geht hier einfach 
nur darum, daß halt nicht exakt die dort angegebenen Zeilen dastehen 
müssen, sondern alles, was im Prinzip dasselbe ist, also auch:
typedef int frobooz;
#define fubar void

frobozz main(fubar);
{
}

oder:
typedef int  foo;
typedef char* bar;
#define blah main(
#define blub foo argc,
#define boing bar* argv)

foo blah blub boing
{
}


erlaubt sind. Das Semikolon hab ich beim Entfernen der Fußnote 
verschluckt.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Übermäßig erleuchtend ist auch die rationale hier nicht:

``... While many implementations support more than two arguments to
main, such practice is neither blessed nor forbidden by the Standard;
a program that defines main with three arguments is not strictly
conforming (see §J.5.1.).''

Ähnlich dürfte also auch die Lage für »void main(void)« sein: not
strictly conforming, aber nicht verboten.  Daher halt auch kein
Fehler, sondern eine Warnung.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könnte es sein, daß diese Diskussion reichlich akademisch ist? Auf 
welchem betriebssystemlosen System (und darum dürfte es sich wohl bei 
den meisten µCs hier handeln) ist es a) relevant, was der C-Startup-Code 
an main() übergibt und b) was main() zurückgibt? main() enthält auf µCs 
eine Endlosschleife, beendet sich also sowieso nicht ...

Nicht, daß ich kein Faible für sprachliche Spitzfindigkeiten hätte, auch 
"shall" ist wunderbar ("thou shalt commit adul_tery**", um mal ein 
quasiliterarisches Zitat* anzubringen) ...


*) "Good Omens" von Neil Gaiman und Terry Pratchett
**) GRR! "Your post seems to contain Spam: "ad*lt".

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Könnte es sein, daß diese Diskussion reichlich akademisch ist?

Ja.

> Auf welchem betriebssystemlosen System (und darum dürfte es sich wohl
> bei den meisten µCs hier handeln) ist es a) relevant, was der
> C-Startup-Code an main() übergibt und b) was main() zurückgibt? main()
> enthält auf µCs eine Endlosschleife, beendet sich also sowieso
> nicht ...

Sagen wir's mal so: Wenn ich die Wahl hab, es formal korrekt zu machen 
oder so daß es mit ziemlicher Sicherheit immer noch funktioniert, aber 
eigentlich falsch ist, dann entscheide ich mich für ersteres.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Übrigens ist das in C++ eindeutiger definiert. Aber daraus sollte man 
keine Rückschlüsse darauf ziehen, was in C eigentlich gemeint war. 
Trotzdem hier mal der entsprechende Ausschnitt aus 14882:
A program shall contain a global function called main, which is the designated start of the program. [...]

An implementation shall not predefine the main function. This function
shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations
shall allow both of the following definitions of main:

        int main() { /* ... */ }

  and

        int main(int argc, char* argv[]) { /* ... */ }

  

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
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
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 bestätigst du, die Nutzungsbedingungen anzuerkennen.