Hallo,
ich versuche mittels printf() eine Ausgabe zu drucken. Dies
funktioniert auch, allerdings funktioniert die Formatierung nicht
richtig.
Beispiele:
printf("huhu\n") -> huhu
printf("test %d", 5) -> test 3568
Ich verwende den Tasking compiler auf einem C167 Prozessor, Modell
small.
Laut Doku unterstützt das small Modell keine Formatierung, also habe ich
noch die Library fmtiosm.lib dazugelinkt. Das hat nicht nicht geholfen.
Hab auch noch beim Compiler die Option "-libfmtiom" gesetzt, brachte
aber auch keine Verbesserung.
Ich würde statt Konstanten mal echte Variablen versuchen.
printf will doch nach dem Formatstring einen Zeiger auf das Argument
bzw. die Argumente haben. Ich könnte mir vorstellen, das das bei C auf
dem Mikrocontroller schief gehen kann.
Selbst auf dem Host klappt nicht alles 100%ig:
Es scheint, dass die Varargs (stdarg.h) nicht funktionieren. Das kann
bei bestimmten Architekturen unter anderem daran liegen, dass der
Compiler keinen Prototypen für die vararg-Funktion (wie z.B. printf)
gesehen hat. Hast du stdio.h included? Evtl selbst mal nen Prototype
angelegt? ("extern int printf(const char *, ...);"). Schreib mal ne
eigene vararg-Funktion (mit Pointern und ints) zum Testen. Was macht:
printf("a %s %d %s\n", "b",42,"c"); und printf("a %d %s", 42, "b");
Bernd schrieb:> Ich würde statt Konstanten mal echte Variablen versuchen.
Wo ist da bei Call-by-Value der Unterschied.
> printf will doch nach dem Formatstring einen Zeiger auf das Argument> bzw. die Argumente haben.
Nein. Es sei denn, es sind Strings. Und selbst Stringliterale zerfallen
in eine Adresse auf das erste Zeichen
Bernd schrieb:> Selbst auf dem Host klappt nicht alles 100%ig:I-002: Start of CntInfo> test -u: 4294967198
Was erwartest du bei einem unsigned int (%u) und negativen Werten (-98)?
Andy schrieb:> Laut Doku unterstützt das small Modell keine Formatierung,
Doku richtig lesen, das steht da nicht. Da steht:
> This SMALL version does not contain the required functionality to handle> precision specifiers and floating point I/O
Formatierung wird also sehr wohl unterstützt (auch bei SMALL), lediglich
precision specifiers und floating point nicht.
Bis zum Beweis des Gegenteils würde ich davon ausgehen, daß
#include <stdio.h>
vergessen wurde.
Hallo zusammen,
vielen Dank für eure zahlreichen Antworten.
Das Problem ist nun gelöst. Des Rätsels Lösung war, wie foobar
geschrieben hat, tatsächlich ein fehlender #include von <stdio.h>.
Habs zwar includiert, aber in einer Datei, wo ein printf ohne
Formatierung verwendet wurde. Habs jetzt mal nochmals in der Datei
includiert, in der die printf Formatierung verwendet wurde und es
funktionierte. :-)
Ausgaben für folgenden Code:
Andy schrieb:> Habs zwar includiert, aber in einer Datei, wo ein printf ohne> Formatierung verwendet wurde. Habs jetzt mal nochmals in der Datei> includiert, in der die printf Formatierung verwendet wurde und es> funktionierte. :-)
Jede .c Datei wird für sich alleine compiliert. Die weiß nicht, was in
anderen Dateien abgeht.
Um an diese Informationen bereitzustellen, gibt es die Header-Dateien.
Wenn du in einer Datei etwas aus einem anderen Modul brauchst, gibt es
ein include.
Erst danach werden die (aus den .c entstandenen) Object-Dateien zusammen
gebunden (gelinkt).
Andy schrieb:> tatsächlich ein fehlender #include von <stdio.h>
Das muss aber eine Warnung vom Compiler geben.
(Beim Aufruf von printf oder anderen Funktionen aus stdio.h)
Wenn nicht, daa musst du den Warnlevel erhöhen.
Behandele Warnungen wie Fehler (beseitige deren Ursache)
Einfach mal so in den Raum geworfen
Es ist keine gute Idee (Embedded) SW zu testen so lange noch Warnungen
ausgegeben werden oder man mit der Quelltext Formatierung noch nicht
zufrieden ist. Bzw. man sich noch nicht an die Code Styles hält
Blume schrieb:> Es ist keine gute Idee (Embedded) SW zu testen so lange> noch Warnungen ausgegeben werden oder man mit der Quelltext> Formatierung noch nicht zufrieden ist.
Im Rahmen der Möglichkeiten teste ich während der Entwicklung
ununterbrochen. Nichts ist schlimmer, als Probleme mit falschen Annahmen
(versuchen) zu lösen. Daher achte ich auf zügige Turnaround-Zeiten
(Dateiänderung -> Ergebnis im Log).
Markus F. schrieb:> Wenn Du das in Gänze verstanden hast, hast Du eine Menge über C gelernt.
Nicht über C selbst, sondern darüber, wie Compiler intern
Funktionsaufrufe umsetzen. Auf C-Ebene ist es einfach nur undefiniertes
Verhalten.
Hallo zusammen,
@MaWin: Der verwendete Compiler ist ein Tasking v8.5 compiler.
@DirkB: Bei dem Compiler kann man irgendwie keine Warnlevel erhöhen. Das
gibt es da wohl nicht. Was geht ist bestimmte Warnungen komplett
deaktivieren (zum Beispiel sind bei mir deaktiviert: -w68 -w91 -w27
usw.)
68: function xxx, parameter yyy not used
91: no prototype of function xxx
27: unexpected text after control
Vermutlich fällt der besagte Fehler unter Warnung 91? Werds mal
probieren. Hab leider davon jede Menge Warnungen. Weiss nicht genau
warum.
Andere Frage dazu: Sind die Warnungen schlimm bzw. können Sie Probleme
verursachen? Programm scheint gut zu laufen, nur gelegentlich gibt's
Abstürze, aber wohl aus anderen Gründen.
Das Problem ist, ich verwende hier Rhapsody und dies generiert mir
überall den Code. Für Funktionen werden stets Parameter verwendet, die
zum Teil nicht verwendet werden (Warning 68). Auch bei Warning 27 werden
zum Beispiel nach #endif Strichpunkt (;) Zeichen eingefügt, welche die
Warnung 27 verursachen.
Grüße, Andy
Warnungen haben ihren Sinn, sie einfach blind abzuschalten kann nach
hinten losgehen (hast du ja gerade gesehen).
Die Warnung 68 abzuschalten kann ich verstehen. Sie soll vor
Tippfehlern warnen. Die übliche Methode, sie "abzuschalten" ist ein:
1
(void)yyy;/*unused*/
im Body von xxx. Einige benutzen ein entsprendes Makro: UNUSED(yyy);
Warnung 91 sollte man auf Systemen, die je nach Prototype
unterschiedlichen Kode generieren, nie abschalten - umschalten auf ERROR
wäre eher angebracht.
Die Warnung 27 solltest du einfach im Kode korrigieren. Hinter #endif
gehört kein Semikolon. Früher war da mal beliebiger Text erlaubt,
heutzutage macht man da einen richtigen Kommentar raus (#endif
/*MSDOS*/)
ist gültiger Code, macht aber bestimmt nicht das, was man möchte.
Darum gibt der Compiler eine Warnung
Code kann man auch mit hohem Warnlevel ohne Warnungen übersetzen.