Hallo, ich möchte gerne eine long Variable mit printf am Terminal ausgeben. Ich hab schon gesucht aber %li, %lu, %ld funktionieren nicht. Ich benutze Codevision zum Programmieren. Mit %i funktioniert es aber dann hab ich immer einen Überlauf. Danke
Hmm, im AVR-GCC geht das (und es geht genau so), und in dessen Forum befindest du dich hier... Was sagt denn die Dokumentation deines Compilers?
Die Dokumentation von Codevision sagt leider nur etwas zu float, int, char, hex, usw. leider nichts zu long.
%ld ist schon voll o.k. so für konforme C-Compiler. In der Codesammlung hat jemand nur für Codevision %ald gepostet, keine Ahnung, was das bedeutet. Peter
Oje, sonst hatte ich mit Codevision nie Sorgen. Muss mich vielleicht doch mal umgewöhnen. %ald funktioniert auch nicht.
Ich arbeite mit dem arm-elf-gcc, und hab gerade das gleiche Problem. Ich hab einen 64-bit integer, den ich per printf mit %ld an das Terminal senden möchte. Leider kommen nur kryptische Zeichen an. %ld erwartet aber auch einen long int, aber int64_t ist mit long long definiert. gibts dafür eine einfache Lösung?
Anscheinend kann sies nicht. Hier das Programm:
1 | #include <board.h> |
2 | #include <pio/pio.h> |
3 | #include <dbgu/dbgu.h> |
4 | |
5 | #include <stdio.h> |
6 | #include <stdint.h> |
7 | |
8 | /// Pio pins to configure.
|
9 | static const Pin pins[] = {PINS_DBGU}; |
10 | |
11 | int main(void) |
12 | {
|
13 | int32_t l1,l2; |
14 | int64_t l3; |
15 | |
16 | |
17 | PIO_Configure(pins, PIO_LISTSIZE(pins)); |
18 | DBGU_Configure(DBGU_STANDARD, 115200, BOARD_MCK); |
19 | printf("\n-- ATMEL ARM7 Dummy Project 1.4 --\n\n"); |
20 | |
21 | l1=2000000000; // 2 Mrd |
22 | l2=0x77359400; // 2 Mrd |
23 | l3=(int64_t)l1*l2; |
24 | printf("2Mrd * 2Mrd = %lld\n",l3); |
25 | |
26 | return 0; |
27 | }
|
der GDB zeicht in Eclipse für l3 das richtige Ergebnis an. Als Ausgabe erhelte ich im GtkTerm
1 | -- ATMEL ARM7 Dummy Project 1.4 -- |
2 | 2Mrd * 2Mrd = ®ÊÀØ&ÈúËSÒ°KÜeý^Á |
3 | ºŸ2äůWªD1U/êîvkÕáꦂ @€6$ |
Wenn du es nur als Debug brauchst, nimm Hex ausgabe und mach aus dem int64_t einen int32_t mittels cast im Printf sowie dasselbe nochmals inkl vorigem shift. Mußt die Reihenfolge usw halt ausprobieren, daß es klappt (big endian/little endian). Sonst, unter Unix/Linux funktioniert es mit ll L oder q prefix, gcc kann alle, die Windows Version von GCC scheitert an long long, das ist ein bekannter Fehler von GCC, hängt aber nicht direkt von den Sourcen ab, eher vom verwendeten Windows-Compiler, um die GCC sourcen zu erstellen.
ich meinte natürlich immer den cross-compiler, nicht nativen Unix Compiler.
> hängt aber nicht direkt von den Sourcen ab, eher vom verwendeten > Windows-Compiler, um die GCC sourcen zu erstellen. Das ist aus zweierlei Gründen zu bezweifeln, einerseits wird kein Compiler verwendet, um "die GCC sourcen zu erstellen", andererseits wird gcc auch unter Windows mit sich selbst übersetzt.
Das ist aber leider so. Windows Ports werden meistens mit MING compiliert, eine GCC Portierung auf Windows, welche die Newlib benutzt. Bei dieser Lib existiert kein printf für ll und L ist da ein Synonym für long double. Bei ll: behavior is undefined, laut doc. Da GCC selbst kein long long printf hat, hat er Probleme damit, so eines zu generieren. Warscheinlich testet er das printf selbst oder so, weiß ich nicht, aber ich kenne mehrere Mailing-Lists, welche das Problem aufgeworfen hatten, und da es teilweise Unix Portierung waren, wie *BSD usw kam dann auch eine Antwort von einem GCC Entwickler, der das natürlich besser begründet hat, aber im Prinzip ist es eine Limitierung der Runtime des Compilers, mit dem GCC selbst compiliert wurde.
ok, sogenannte tippfehler, nicht erstellen, sondern compilieren. habs jetzt erst gecheckt, sorry
chris wrote: > Das ist aber leider so. Windows Ports werden meistens mit MING > compiliert, > eine GCC Portierung auf Windows, welche die Newlib benutzt. Der Haken dabei ist wohl, dass newlib halt kein richtiges Projekt ist, sondern lieblos und wenig gepflegt von irgendwoher zusammen gezogener Sourcecode für eine (einigermaßen) Standardbibliothek, die nicht den Limitierungen der (L)GPL unterworfen ist. So findet sich da offenbar eine uralte (lange vor ISO C99 geschaffene) Variante der BSD-libc wieder, die damals L als modifier für long long int benutzt hat. Wenn die Leute mal ihre Quellen von einem einigermaßen aktuellen FreeBSD aktualisieren würden, dann wäre das Dilemma behoben. Für Karl heißt das aber wohl, dass er sich auch mit %Ld behelfen kann.
Alos %Ld funktioniert genausowenig wie %lld... Ich brauch die Funktion grad nicht wirklich, aber trotzdem schade. lg
Dann kannst du dir nur mit dem Selbstportieren einer der diversen BSD-Bibliotheken behelfen, wenn du's mal brauchst.
Karl Zeilhofer wrote:
> hört sich nach viel arbeit an...
Ist an einem Abend gemacht. Man sollte sich unterschiedliche
Versionen vornehmen, aktuelle Versionen sind auf Grund der später
eingebauten C99-Features u. U. etwas komplexer geworden. Ggf. mit
einem ursprünglichen 4.4BSD beginnen, da bin ich mir nur nicht ganz
sicher, ob's da schon long long gab.
Für solche Debug-Zwecke hatte ich mir deshalb mal eine eigene eingedampfte Version von printf gestrickt. Schon auf Platzgründen wollte ich beim ARM auf die newlib verzichten- Sollte ziemlich universell einsetzbar sein, sofern alloca() existiert und "unsigned long long" der maximal verfügbare Integer-Typ ist. Ist Originalfassung, die Includes müssen angepasst werden, config,h kann man streichen.
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.