Forum: Compiler & IDEs long ausgabe mit printf


von Christopher (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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?

von Christopher (Gast)


Lesenswert?

Die Dokumentation von Codevision sagt leider nur etwas zu
float, int, char, hex, usw. leider nichts zu long.

von Peter D. (peda)


Lesenswert?

%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

von Christopher (Gast)


Lesenswert?

Oje, sonst hatte ich mit Codevision nie Sorgen. Muss mich vielleicht 
doch mal umgewöhnen. %ald funktioniert auch nicht.

von Karl Z. (griffin27)


Lesenswert?

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?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wenn deine Bibliothek es kann: %lld.

von Karl Z. (griffin27)


Lesenswert?

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ªD—1U/êîvkÕáꦂ @€6$

von chris (Gast)


Lesenswert?

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.

von chris (Gast)


Lesenswert?

ich meinte natürlich immer den cross-compiler, nicht nativen Unix 
Compiler.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> 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.

von chris (Gast)


Lesenswert?

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.

von chris (Gast)


Lesenswert?

ok, sogenannte tippfehler, nicht erstellen, sondern compilieren.
habs jetzt erst gecheckt, sorry

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Karl Z. (griffin27)


Lesenswert?

Alos %Ld funktioniert genausowenig wie %lld... Ich brauch die Funktion 
grad nicht wirklich, aber trotzdem schade.

lg

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dann kannst du dir nur mit dem Selbstportieren einer der diversen
BSD-Bibliotheken behelfen, wenn du's mal brauchst.

von Karl Z. (griffin27)


Lesenswert?

hört sich nach viel arbeit an...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von (prx) A. K. (prx)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.