Hallo ich möchte eine stinknormale mudolo Funktiopn anweden in meinem Code. Einmal benutzte ich x%8 -> das funktioniert weil ja es imPrinzip nur eine shift operation ist nun möchte ich aber x%y berechnen lassen und erfahre, daß ich von gcc diese zeile mit einem <source line is not available> quitiert bekomme! Kann mir jemand sagen wo ich die passende Library mit der passenden Funktion herbekomme oder wie ich sonst das problem lösen kann? Vielen Dank Tobias
x%y ist ein korrekter C-Ausdruck, wenn x und y ganzzahlige Datentypen (also bspw. auch uint8_t) sind. Du brauchst dazu weder ein Header-File zu includen noch eine spezielle Library einzubinden (libc genügt, die wird aber automatisch gelinkt). Der Fehler liegt also außerhalb dieses Ausdrucks.
Was ich damit sagen wollte (und auch vorher schon Rufus), ist, dass du vielleicht mehr Hilfe bekommst, wenn du etwas mehr als drei Zeichen von deinem Quellcocde postest, mindestens so viel, dass andere dein Problem reproduzieren können.
Tobias Eckhardt wrote: > Einmal benutzte ich x%8 -> das funktioniert weil ja es imPrinzip nur > eine shift operation ist Nein ist es nicht! Es ist ein AND: x%8 == x&7 Peter
Peter Dannegger wrote:
> Es ist ein AND:
Wohl wahr, immerhin. Scherzfrage: was ist dann:
(x + 1) % 8
Andreas Kaiser wrote: > Peter Dannegger wrote: > >> Es ist ein AND: > > Wohl wahr, immerhin. Scherzfrage: was ist dann: > (x + 1) % 8 (x + 1) % 8 ist natürlich gleich (x + 1) AND 7 ;)
> (x + 1) % 8 > ist natürlich gleich > (x + 1) AND 7 Na dann probier's mal aus (gcc, unsigned char).
Nächstes Nein ;-) x % 8 == x & 7 gilt nur solange x kein Vorzeichen hat -11 % 8 == -3 -11 & 7 == 5 "beide sind uint8_t!" übersehen...
Ist hier uint8_t, also eindeutig (s.o.). Nur ist die Weisheit von gcc begrenzt, der weiss nicht dass x+1 nie negativ wird und dividiert hier unverdrossen per runtime lib.
Ich weiß nicht was der AVR-GCC macht, auf x86 und ARM kommt das raus was man erwarten würde (-O3):
1 | calc: |
2 | pushl %ebp |
3 | movl %esp, %ebp |
4 | movzbl 8(%ebp), %eax |
5 | popl %ebp |
6 | addl $1, %eax |
7 | andl $7, %eax |
8 | ret |
Bei -Os nimmt er idivl ohne dabei etwas zu sparen. Etwas kryptischer sieht das ganze auf PowerPC aus:
1 | _calc: |
2 | addi r3,r3,1 |
3 | srawi r0,r3,3 |
4 | addze r0,r0 |
5 | slwi r0,r0,3 |
6 | subf r3,r0,r3 |
7 | rlwinm r3,r3,0,0xff |
8 | blr |
Ich glaube, der OP hat lediglich ein Problem, dass ihm hier irgendwo der Optimierer was wegoptimiert hat, sodass er auf dieser Zeile keinen Brechpunkt setzen kann oder so ähnlich. Der resultierende Code wird völlig in Ordnung sein und das gewünschte (oder zumindest das hingeschriebene :) ausführen, es ist nur nicht ganz einfach, das mit dem Debugger nachzuvollziehen.
1 | unsigned char a, b; |
2 | |
3 | void f(void) |
4 | {
|
5 | a = (b + 1) % 8; |
6 | }
|
cygwin gcc (3.4.4):
1 | _f: |
2 | movzbl _b, %eax |
3 | incl %eax |
4 | movl %eax, %edx |
5 | andl $504, %edx |
6 | subl %edx, %eax |
7 | movb %al, _a |
8 | ret |
avr-gcc:
1 | f: |
2 | lds r24,b |
3 | clr r25 |
4 | adiw r24,1 |
5 | ldi r22,lo8(8) |
6 | ldi r23,hi8(8) |
7 | rcall __divmodhi4 |
8 | sts a,r24 |
9 | ret |
Guten Morgen, da meldet sich der Übeltäter mal wieder! Das Problem hat sich zum Glück nicht gelöst, aber ich kann es umgehen. Es lag an Eclipse und GCC. Sowit wie ich das Verstehe können die mir einfach beim Debuggen dieser Zeile nicht den Ort zeigen der diese Berechnung genauer beschreibt, ABER berechnet wie es korrekt und somit ist es kein inhaltlicher Fehler meinerseits. Danke für eurer Wissen, das mit dem shiften bei %8 war mir neu. Eine schöne Restwoche. Tobi
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.