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
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
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 ....
@Hans-jürgen Herbert: Das ist genau das was gefehlt hat ;-) Nun ist das Problem behoben. Danke nochmals, Thomas
Ansonsten würde auch gehen: #define TESTSTRING_LENGTH (sizeof(TESTSTRING)-1)
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).
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,
> für eine hosted application gibt's zwei genau vorgeschriebene > Möglichkeiten, wie main() definiert werden darf Da irrst du. Aus ISO/IEC9899:1999:
1 | The function called at program startup is named main. The implementation |
2 | declares no prototype for this function. It shall be defined with a return |
3 | type of int and with no parameters: |
4 | int main(void) { /* ... */ } |
5 | |
6 | or with two parameters (referred to here as argc and argv, though any |
7 | names may be used, as they are local to the function in which they are |
8 | declared): |
9 | int main(int argc, char *argv[]) { /* ... */ } |
10 | |
11 | 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.
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.
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.
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.
Ja, die Formulierung ist recht verwaschen. Ich denke, die zielt darauf ab, dass man die historische Unix-Implementierung
1 | 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. ;-)
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.CatalogueDetail?CSNUMBER=29237 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
> 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:
1 | typedef int frobooz; |
2 | #define fubar void
|
3 | |
4 | frobozz main(fubar); |
5 | {
|
6 | }
|
oder:
1 | typedef int foo; |
2 | typedef char* bar; |
3 | #define blah main(
|
4 | #define blub foo argc,
|
5 | #define boing bar* argv)
|
6 | |
7 | foo blah blub boing |
8 | {
|
9 | }
|
erlaubt sind. Das Semikolon hab ich beim Entfernen der Fußnote verschluckt.
Ü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.
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".
> 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.
Ü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:
1 | A program shall contain a global function called main, which is the designated start of the program. [...] |
2 | |
3 | An implementation shall not predefine the main function. This function |
4 | shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations |
5 | shall allow both of the following definitions of main: |
6 | |
7 | int main() { /* ... */ } |
8 | |
9 | and |
10 | |
11 | int main(int argc, char* argv[]) { /* ... */ } |
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.