Grias eich,
soweit ich mich erinnern kann, werden die Ausdrücke von links nach
rechts ausgewertet, was dann dafür sorgen müsste, dass erst ADCL dann
ADCH gelesen werden, oder?
Der ADC des AVRs möchte das ja in der Reihenfolge ... Ich wollte nur
sicher gehen, dass das so passt und dass mir irgendeine Optimierung
nichts versaut :)
@ Mampf F. (mampf)
>sicher gehen, dass das so passt :)
Mach es einfach so.
uint16_t adc_val = ADCW;
Der avr gcc macht das dann schon richtig für dich, denn der weiß, wie
man 16 Bit Register auf dem AVR liest.
Mampf F. schrieb:> Der ADC des AVRs möchte das ja in der Reihenfolge ... Ich wollte nur> sicher gehen, dass das so passt und dass mir irgendeine Optimierung> nichts versaut :)
warum machst du dann nicht einfach
Mampf F. schrieb:> soweit ich mich erinnern kann, werden die Ausdrücke von links nach> rechts ausgewertet,
Keineswegs, die Reihenfolge hängt vom Compiler ab und ist praktisch
zufällig. Daher sollte man auf jeden Fall die anderen bereits genannten
Möglichkeiten verwenden...
Dr. Sommer schrieb:> Mampf F. schrieb:>> soweit ich mich erinnern kann, werden die Ausdrücke von links nach>> rechts ausgewertet,>> Keineswegs, die Reihenfolge hängt vom Compiler ab und ist praktisch> zufällig. Daher sollte man auf jeden Fall die anderen bereits genannten> Möglichkeiten verwenden...
Mmmhmm, so ganz kann das nicht stimmen ... Oooooder, ich verwechsel das
mit Conditional Ausdrücken, wie sie bei Ifs vorkommen ... Soweit ich
mich erinnern kann, kann man sich da auf die Reihenfolge verlassen.
Mampf F. schrieb:> Dr. Sommer schrieb:>> Mampf F. schrieb:>>> soweit ich mich erinnern kann, werden die Ausdrücke von links nach>>> rechts ausgewertet,>>>> Keineswegs, die Reihenfolge hängt vom Compiler ab und ist praktisch>> zufällig. Daher sollte man auf jeden Fall die anderen bereits genannten>> Möglichkeiten verwenden...>> Mmmhmm, so ganz kann das nicht stimmen ... Oooooder, ich verwechsel das> mit Conditional Ausdrücken, wie sie bei Ifs vorkommen ... Soweit ich> mich erinnern kann, kann man sich da auf die Reihenfolge verlassen.
Bei
1
ADCL|(ADCH<<8)
ist zwischen dem Zugriff auf ADCL und ADCH kein Sequence Point, und da
hülft auch kein volatile. Wenn ADCL vor ADCH gelesen werden soll, dann
also
1
uint8_tadcl=ADCL;
2
uint16_tadc_val=adcl|(ADCH<<8);
Aber warum den Kopf zerbrechen? Die beste Lösung steht bereits in der
1. Antwort.
Mampf F. schrieb:> Dr. Sommer schrieb:>> Mampf F. schrieb:>>> soweit ich mich erinnern kann, werden die Ausdrücke von links nach>>> rechts ausgewertet,>>>> Keineswegs, die Reihenfolge hängt vom Compiler ab und ist praktisch>> zufällig. Daher sollte man auf jeden Fall die anderen bereits genannten>> Möglichkeiten verwenden...>> Mmmhmm, so ganz kann das nicht stimmen ... Oooooder, ich verwechsel das> mit Conditional Ausdrücken, wie sie bei Ifs vorkommen ... Soweit ich> mich erinnern kann, kann man sich da auf die Reihenfolge verlassen.
Vielleicht erinnerst du die dich an deine Erinnerung nicht richtig oder
auch nur unvollständig. Komm wieder, wenn du eine sichere Auskunft geben
kannst. So'n Wischiwaschi hilft hier keinem.
krampf schrieb:> Vielleicht erinnerst du die dich an deine Erinnerung nicht richtig oder> auch nur unvollständig.
Nein, ich bin mir absolut sicher ... Bei if-Expressions kann mann sich
auf die Auswerte-Reihenfolge verlassen ... 100%
Früher habe ich oft Konstrukte wie:
if (ptr && ptr.bla()) { ... }
verwendet ... Das geht nur, wenn die Expression von links nach rechts
abgearbeitet wird.
§5.14
Unlike &, && guarantees left-to-right evaluation: the second operand is
not evaluated if the first operand is false.
§5.15
Unlike |, || guarantees left-to-right evaluation; moreover, the second
operand is not evaluated if the first operand evaluates to true.
Aber das ist halt nur bei && und || richtig ... Insofern war meine
Unsicherheit aus dem ersten Post richtig, weswegen ich gefragt hatte :)
Mampf F. schrieb:> Nein, ich bin mir absolut sicher ... Bei if-Expressions kann mann sich> auf die Auswerte-Reihenfolge verlassen ... 100%
Nein, mit dem if hat das überhaupt nichts zu tun. Bei
1
if(a|b)...
ist die Auswertereihenfolge von a und b nicht festgelegt.
Bei
1
if(a||b)...
hingegen schon. Das liegt aber nicht am if, sondern am ||.
Bei
1
c=a||b;
wird, obwohl kein if dasteht, ebenfalls a vor b ausgewertet (und b auch
nur dann, wenn a=0 ist).
Aber du hast ja den entsprechenden Abschnitt aus der Norm gerade selber
zitiert.
K&R C Reference Manual, Expressions (frei übersetzt):
Es ist dem Compiler überlassen, ob er von links nach rechts oder von
rechts nach links übersetzt, auch, wenn der Ausdruck Nebeneffekte
beinhaltet. Wenn eine bestimmte Reihenfolge unbedingt eingehalten werden
muss, müssen explizit temporäre Variable benutzt werden.