Forum: Compiler & IDEs if (uint16_t) --blink) == 0 Ok. if(--blink == 0 ) nicht ok?


von Jörg E. (jackfritt)


Lesenswert?

Hallo,

ich stehe auf dem Schlauch. Wieso erkennt der Compiler im oberen Teil 
nicht einen 16 bit wert? Beides compiliert ohne Hinweis bzw. Fehler.
1
#include <avr/io.h>
2
#include <inttypes.h>
3
4
uint16_t blink=24;
5
6
int main()
7
{
8
#if 0
9
  if(--blink == 0 ){
10
    PORTB = PINB ^ ( 1 << PB0 );
11
    blink=24;
12
  }
13
#else
14
  if( ((uint16_t) --blink) == 0 ){
15
    PORTB = PINB ^ ( 1 << PB0 );
16
    blink=24;
17
  }
18
#endif
19
}

: Bearbeitet durch User
von ich (Gast)


Lesenswert?

Dir ist schon bewusst, dass der erste Teil gar nicht compiliert wird, 
weil du den über den Preprocessor auskommentierst?

von Ingo (Gast)


Lesenswert?

Jörg Esser schrieb:
> #if 0
??? 0 wird niemals 1 !!!

von Detlef K. (adenin)


Lesenswert?

Ingo schrieb:
> Jörg Esser schrieb:
>> #if 0
> ??? 0 wird niemals 1 !!!

Wenn Null besonders groß ist, ist es fast soviel, wie ein bisschen Eins.

von WasFürDussel (Gast)


Lesenswert?

Er meint eine der beiden Versionen!

#if 0 ODER #if 1

von ich (Gast)


Lesenswert?

nochmal: Die Frage ist ziemlich scheiße gestellt... Der Compiler erkennt 
was nicht?? Was meinst du damit?...

von WasFürDussel (Gast)


Lesenswert?

ich schrieb:
> nochmal: Die Frage ist ziemlich scheiße gestellt... Der Compiler erkennt
> was nicht?? Was meinst du damit?...

Feiner hätte ich es nicht ausdrücken können.

von Detlef K. (adenin)


Lesenswert?

Jörg Esser schrieb:
> Wieso erkennt der Compiler im oberen Teil
> nicht einen 16 bit wert?

Woran merkst Du das?
Für die Ausführung des dieses Beispielcodes ist das unbedeutent.

von mimin (Gast)


Lesenswert?

Moment mal,  er hat "beides" geschrieben,  höcshtwahrscheinlich hat er 
#if 0 und #if 1 probiert.

von Thomas E. (thomase)


Lesenswert?

Jörg Esser schrieb:
> ich stehe auf dem Schlauch. Wieso erkennt der Compiler im oberen Teil
> nicht einen 16 bit wert?
Wie kommst du darauf?

>Beides compiliert ohne Hinweis bzw. Fehler.
Natürlich. Beides erzeugt auch identischen Code.

mfg.

: Bearbeitet durch User
von Kaj (Gast)


Lesenswert?

Jörg Esser schrieb:
> #if 0
> #else
> #endif

Das ist so ziemlich die beschissenste art etwas "auszukommentieren"!

von (prx) A. K. (prx)


Lesenswert?

Kaj schrieb:
> Das ist so ziemlich die beschissenste art etwas "auszukommentieren"!

Keep cool. Bei Testcases wie hier ist das völlig normal.

von (prx) A. K. (prx)


Lesenswert?

Jörg Esser schrieb:
> ich stehe auf dem Schlauch.

Ich auch ...

> Wieso erkennt der Compiler im oberen Teil
> nicht einen 16 bit wert?

... weil ich mit diesem Satz nichts anfangen kann.

von bal (Gast)


Lesenswert?

Kaj schrieb im Beitrag #3863492
>
> Das ist so ziemlich die beschissenste art etwas "auszukommentieren"!

Ok. Ich schlage vor:
Du schreibst jetzt, wie du Code kurzfristig "rausnehmen" würdest und ich 
sag dir nachher wieso die Methode vomTO besser ist.

von meckerziege (Gast)


Lesenswert?

Kaj schrieb:
> Jörg Esser schrieb:
>> #if 0
>> #else
>> #endif
>
> Das ist so ziemlich die beschissenste art etwas "auszukommentieren"!

Alternativvorschlag? Mir fallen spontan mehrere Gründe ein, weshalb das 
hier durchaus in Ordnung ist...
Aber lass du mal hören!

von Vim! (Gast)


Lesenswert?

Kaj schrieb:
> Das ist so ziemlich die beschissenste art etwas "auszukommentieren"!

Deshalb erkennen brauchbare Editoren wie der Vim das ja auch und färben 
es entsprechend in Kommentarfarbe ein ;)

von Thomas E. (thomase)


Lesenswert?

Vim! schrieb:
> Editoren

Editoren gibt es nicht. Editor ist Singularetantum, da es nur einen 
Editor gibt.
Wie? Ei, wie heisst der denn?

mfg.

von Detlef K. (adenin)


Lesenswert?

Thomas Eckmann schrieb:
> Vim! schrieb:
>> Editoren
>
> Editoren gibt es nicht. Editor ist Singularetantum, da es nur einen
> Editor gibt.
> Wie? Ei, wie heisst der denn?
>
> mfg.

Der Duden ist anderer Meinung.
http://www.duden.de/rechtschreibung/Editor_Herausgeber

von Daniel H. (Firma: keine) (commander)


Lesenswert?

Vermutung ins Blaue: Compileroptimierung

Für die Variable gilt immer 0 <= blink <= 24. Kann also sein, dass der 
Compiler das in der ersten Version platzsparend in ein uint8_t 
umwandelt. Bei der zweiten Variante hingegen castest du explizit wieder 
zu uint16_t -> keine Optimierung da uint16_t explizit gefordert.

von (prx) A. K. (prx)


Lesenswert?

Thomas Eckmann schrieb:
> Editoren gibt es nicht. Editor ist Singularetantum, da es nur einen
> Editor gibt.

Der Duden lässt das Plural zu, das ist deine Aussage rein 
grammatikalisch wohl nicht ganz zutreffend. Bei der hier etwas 
deplacierten Bedeutung im Verlagswesen klappt das auch nicht, denn 
selbstredend gibt es mehrere Editoren/Herausgeber, andernfalls wäre die 
Medienlandschaft noch trister als sie ohnehin schon ist.

von Thomas E. (thomase)


Lesenswert?

Detlef Kunz schrieb:
> Der Duden ist anderer Meinung.
Auch der Duden ist nicht fehlerfrei.

Daniel H. schrieb:
> Bei der zweiten Variante hingegen castest du explizit wieder
> zu uint16_t -> keine Optimierung da uint16_t explizit gefordert.

Nein. Das gibt beide Male den gleichen Code.

mfg.

von Thomas E. (thomase)


Lesenswert?

A. K. schrieb:
> Der Duden lässt das Plural zu, das ist deine Aussage rein
> grammatikalisch wohl nicht ganz zutreffend. Bei der hier etwas
> deplacierten Bedeutung im Verlagswesen klappt das auch nicht, denn
> selbstredend gibt es mehrere Editoren/Herausgeber, andernfalls wäre die
> Medienlandschaft noch trister als sie ohnehin schon ist.

Nein. Es gibt nur einen Editor. Alles andere ist Spielkram.

mfg.

von Jörg E. (jackfritt)


Lesenswert?

Hmm bei mir gibt es einen Unterschied. Die Variable wird scheinbar 
anders heruntergezählt.
Ich werde mal schaun was mein gcc für einen assembler code ausspuckt.

Sorry für meine Laienhaften Ausführungen aber das is für mich nur Hobby 
bzw. Liebhaberei ;)

von Detlef K. (adenin)


Lesenswert?

Thomas Eckmann schrieb:
> A. K. schrieb:
>> Der Duden lässt das Plural zu, das ist deine Aussage rein
>> grammatikalisch wohl nicht ganz zutreffend. Bei der hier etwas
>> deplacierten Bedeutung im Verlagswesen klappt das auch nicht, denn
>> selbstredend gibt es mehrere Editoren/Herausgeber, andernfalls wäre die
>> Medienlandschaft noch trister als sie ohnehin schon ist.
>
> Nein. Es gibt nur einen Editor. Alles andere ist Spielkram.
>
> mfg.


Autor: Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase)
Hmm, was sind den "thomase" ? Doch nicht etwa die Mehrzahl von dir. ;)

von Thomas E. (thomase)


Lesenswert?

Detlef Kunz schrieb:
> Autor: Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase)
> Hmm, was sind den "thomase" ? Doch nicht etwa die Mehrzahl von dir. ;)

Doch. Normalerweise hast du mich mit Ihr bzw. Euch anzureden.

Jetzt mach hier nicht so einen Wind. Du verstehst das nur nicht.

Das bezog sich einzig auf unseren Linuxfreund, der hier mit seinem vim 
angeben wollte.

Richtige Linuxuser, also die Masochisten unter den Linuxusern, naja 
eigentlich sind das ja alles Masochisten, aber egal.

Also für die richtigen, die knallharten Linuxuser gibt es nur einen 
Editor. Ich hatte ja befürchtet, dass das keiner versteht und extra 
einen Zaunpfahl zum winken eingebaut: Wie? Ei,...

mfg.

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

Jörg Esser schrieb:
> Hmm bei mir gibt es einen Unterschied. Die Variable wird scheinbar
> anders heruntergezählt.
Da musst du dich irren.

Es gibt 2 Regeln:

1. Der Compiler hat immer Recht.
2. Trifft dies ausnahmsweise nicht zu, tritt automatisch Regel 1 in 
Kraft.

Mit anderen Worten: Was der Compiler macht, ist richtig.
Und er gehorcht dir aufs Wort. Und zwar richtig wörtlich. Manchmal gibt 
es allerdings Verständigungsprobleme. Dann kommen die beiden Regeln zum 
Zuge.

Aber das ist hier nicht der Fall. Der zählt runter oder besser er lässt 
runterzählen. Da kann er gar nicht anders.

mfg.

: Bearbeitet durch User
von johnny (Gast)


Lesenswert?

>Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase)

Bist du einer dieser fahrenden Computerbeschwörer deren Kenntnisse man 
sich dann und wann an nicht funktionierenden SOHO Installationen 
überzeugen darf? Zumindest ereilt mich an dieser Stelle so ein 
Eindruck...

MfG

von Thomas E. (thomase)


Lesenswert?

johnny schrieb:
> Bist du einer dieser fahrenden Computerbeschwörer deren Kenntnisse man

"von deren Kenntnissen" heisst das.
Deine Kommataste funktioniert auch nicht.

Das andere erzähl ich dir, wenn du mir erzählst, was du für eine 
Flitzpiepe bist.

mfg.

von johnny (Gast)


Lesenswert?

:P also ja.

Na dann wünsch ich dir noch viel Spaß.

MfG

P.S.: Haste recht, ich möchte ein "n" kaufen.

von Thomas E. (thomase)


Lesenswert?

johnny schrieb:
> Na dann wünsch ich dir noch viel Spaß.
Danke.

Von dem, was ich mache, da träumst du nur von.

mfg.

von Bastler (Gast)


Lesenswert?

Jörg Esser schrieb:
> Hmm bei mir gibt es einen Unterschied. Die Variable wird scheinbar
> anders heruntergezählt.
> Ich werde mal schaun was mein gcc für einen assembler code ausspuckt.
>
> Sorry für meine Laienhaften Ausführungen aber das is für mich nur Hobby
> bzw. Liebhaberei ;)

Pack doch einfach mal das .lss File hier rein, dann können wir sehen wie 
unterschiedlich das Ergebnis ausfällt.

von johnny (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Von dem, was ich mache, da träumst du nur von.

Da gratuliere ich recht herzlich und lasse das mal so stehen :)

MfG

von Sven B. (scummos)


Lesenswert?

Disassemblier' das Ergebnis, alles andere ist doch Raterei :)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Esser schrieb:
> Wieso erkennt der Compiler im oberen Teil nicht
> einen 16 bit wert?

Weil da kein 16-Bit Wert im "oberen Teil" ist:

> #include <avr/io.h>
> #include <inttypes.h>

von Thomas E. (thomase)


Lesenswert?

Sven B. schrieb:
> Disassemblier' das Ergebnis, alles andere ist doch Raterei :)

Das ist keine Raterei. Das Casten ändert gar nichts. Und beides erzeugt 
identischen Code.
Mehr kann man zu diesem Codefetzen nicht sagen. Es sei denn er zeigt den 
ganzen Code. Vielleicht ist es ja doch Raterei.

mfg.

von Sven B. (scummos)


Lesenswert?

Thomas Eckmann schrieb:
> Sven B. schrieb:
>> Disassemblier' das Ergebnis, alles andere ist doch Raterei :)
>
> Das ist keine Raterei. Das Casten ändert gar nichts. Und beides erzeugt
> identischen Code.

Naja, wir wissen ja nichtmal welcher Compiler das ist, von daher würde 
ich sagen, mal schauen schadet sicher nichts.

von Le X. (lex_91)


Lesenswert?

Thomas Eckmann schrieb im ganzen Thread hier:
> ...habedahabedahabeda...

Was war denn mit dir gestern Abend los?
Es ist nicht gerade gesund, sich vorm Schlafen gehen so aufzuregen. 
Entspann mal!

von Dieter F. (Gast)


Lesenswert?

Jörg Esser schrieb:
> Die Variable wird scheinbar
> anders heruntergezählt.

Und woran erkennst Du das?

von Bernd K. (prof7bit)


Lesenswert?

Thomas Eckmann schrieb:

> Das bezog sich einzig auf unseren Linuxfreund, der hier mit seinem vim
> angeben wollte.

Eclipse CDT kann das auch (unzutreffende #ifdef ausgrauen). Sogar wenn 
man es unter Windows benutzt. Macht jede ordentliche C/C++ IDE.

von Rolf M. (rmagnus)


Lesenswert?

Kaj schrieb:
> Jörg Esser schrieb:
>> #if 0
>> #else
>> #endif
>
> Das ist so ziemlich die beschissenste art etwas "auszukommentieren"!

Mir fällt keine bessere ein, dafür aber mehrere, die schlechter sind.

von Michael A. (micha54)


Lesenswert?

Hallo,

kann es sein, dass die erste Variante Blink mit 0 vergleicht, was 0 
ergibt und dieses dann dekrementiert ? Die zweite hat ein paar 
züsätzliche Klammern....

Gruß,
Michael

von Eric (Gast)


Lesenswert?

Michael Appelt schrieb:
> Hallo,
>
> kann es sein, dass die erste Variante Blink mit 0 vergleicht, was 0
> ergibt und dieses dann dekrementiert ? Die zweite hat ein paar
> züsätzliche Klammern....
>
> Gruß,
> Michael

Nein: http://en.cppreference.com/w/c/language/operator_precedence

von Daniel V. (danvet)


Lesenswert?

Jörg Esser schrieb:
> Hallo,
>
> ich stehe auf dem Schlauch. Wieso erkennt der Compiler im oberen Teil
> nicht einen 16 bit wert? Beides compiliert ohne Hinweis bzw. Fehler.
>
1
> #include <avr/io.h>
2
> #include <inttypes.h>
3
> 
4
> uint16_t blink=24;
5
> 
6
> int main()
7
> {
8
> #if 0
9
>   if(--blink == 0 ){
10
>     PORTB = PINB ^ ( 1 << PB0 );
11
>     blink=24;
12
>   }
13
> #else
14
>   if( ((uint16_t) --blink) == 0 ){
15
>     PORTB = PINB ^ ( 1 << PB0 );
16
>     blink=24;
17
>   }
18
> #endif
19
> }
20
>

Ich könnte mir vorstellen, dass der Compiler optimiert.
Da nur 0..24 als Wert vorkommt, reicht es, diesen Wert als 8Bit zu 
speichern (AVR 8Bit Controller), dafür ist nur ein 8Bit-Register 
notwendig - im oberen Fall.
Unten castest du explizit zu uint16_t, der Compiler gehorcht aufs Wort 
und belegt 16Bit.

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

Daniel V. schrieb:
> Ich könnte mir vorstellen, dass der Compiler optimiert.
> Da nur 0..24 als Wert vorkommt, reicht es, diesen Wert als 8Bit zu
> speichern (AVR 8Bit Controller), dafür ist nur ein 8Bit-Register
> notwendig - im oberen Fall.
> Unten castest du explizit zu uint16_t, der Compiler gehorcht aufs Wort
> und belegt 16Bit.

Klingt sinnvoll. Bei komplett abgeschalteter Optimierung sollte dann das 
gleiche Ergebnis herauskommen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Daniel V. schrieb:
> Ich könnte mir vorstellen, dass der Compiler optimiert.
> Da nur 0..24 als Wert vorkommt, [...]

Diese Annahme ist falsch, bzw. ein Compiler, der so eine Annahme oder 
darauf basierende Optimierungen macht, ist nicht korrekt.

Beim Aufruf von main ist der Wert der Variablen nämlich nicht bekannt: 
Ein anderes Modul könnte Code vor main ausführen und blink auf einen 
anderen Wert setzen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Ich glaube kaum, dass Jörg mit dem GCC einen Unterschied zwischen den
beiden Varianten feststellen konnte. Ich hab's gerade für verschiedene
Compiler-Versionen, Optimierungsstufen und AVR-Typen ausprobiert. Der
vom Compiler erzeugte Assemblercode hängt in allen Fällen nicht davon
ab, welcher Zweig im #if-#else-#endif aktiv ist.

Ergebnis:
1
avr-gcc-4.2.4 -O0 -mmcu=attiny13        --> gleich
2
avr-gcc-4.2.4 -O0 -mmcu=atmega1280      --> gleich
3
avr-gcc-4.2.4 -O1 -mmcu=attiny13        --> gleich
4
avr-gcc-4.2.4 -O1 -mmcu=atmega1280      --> gleich
5
avr-gcc-4.2.4 -O2 -mmcu=attiny13        --> gleich
6
avr-gcc-4.2.4 -O2 -mmcu=atmega1280      --> gleich
7
avr-gcc-4.2.4 -O3 -mmcu=attiny13        --> gleich
8
avr-gcc-4.2.4 -O3 -mmcu=atmega1280      --> gleich
9
avr-gcc-4.2.4 -Os -mmcu=attiny13        --> gleich
10
avr-gcc-4.2.4 -Os -mmcu=atmega1280      --> gleich
11
12
avr-gcc-4.3.6 -O0 -mmcu=attiny13        --> gleich
13
avr-gcc-4.3.6 -O0 -mmcu=atmega1280      --> gleich
14
avr-gcc-4.3.6 -O1 -mmcu=attiny13        --> gleich
15
avr-gcc-4.3.6 -O1 -mmcu=atmega1280      --> gleich
16
avr-gcc-4.3.6 -O2 -mmcu=attiny13        --> gleich
17
avr-gcc-4.3.6 -O2 -mmcu=atmega1280      --> gleich
18
avr-gcc-4.3.6 -O3 -mmcu=attiny13        --> gleich
19
avr-gcc-4.3.6 -O3 -mmcu=atmega1280      --> gleich
20
avr-gcc-4.3.6 -Os -mmcu=attiny13        --> gleich
21
avr-gcc-4.3.6 -Os -mmcu=atmega1280      --> gleich
22
23
avr-gcc-4.4.7 -O0 -mmcu=attiny13        --> gleich
24
avr-gcc-4.4.7 -O0 -mmcu=atmega1280      --> gleich
25
avr-gcc-4.4.7 -O1 -mmcu=attiny13        --> gleich
26
avr-gcc-4.4.7 -O1 -mmcu=atmega1280      --> gleich
27
avr-gcc-4.4.7 -O2 -mmcu=attiny13        --> gleich
28
avr-gcc-4.4.7 -O2 -mmcu=atmega1280      --> gleich
29
avr-gcc-4.4.7 -O3 -mmcu=attiny13        --> gleich
30
avr-gcc-4.4.7 -O3 -mmcu=atmega1280      --> gleich
31
avr-gcc-4.4.7 -Os -mmcu=attiny13        --> gleich
32
avr-gcc-4.4.7 -Os -mmcu=atmega1280      --> gleich
33
34
avr-gcc-4.5.4 -O0 -mmcu=attiny13        --> gleich
35
avr-gcc-4.5.4 -O0 -mmcu=atmega1280      --> gleich
36
avr-gcc-4.5.4 -O1 -mmcu=attiny13        --> gleich
37
avr-gcc-4.5.4 -O1 -mmcu=atmega1280      --> gleich
38
avr-gcc-4.5.4 -O2 -mmcu=attiny13        --> gleich
39
avr-gcc-4.5.4 -O2 -mmcu=atmega1280      --> gleich
40
avr-gcc-4.5.4 -O3 -mmcu=attiny13        --> gleich
41
avr-gcc-4.5.4 -O3 -mmcu=atmega1280      --> gleich
42
avr-gcc-4.5.4 -Os -mmcu=attiny13        --> gleich
43
avr-gcc-4.5.4 -Os -mmcu=atmega1280      --> gleich
44
45
avr-gcc-4.6.4 -O0 -mmcu=attiny13        --> gleich
46
avr-gcc-4.6.4 -O0 -mmcu=atmega1280      --> gleich
47
avr-gcc-4.6.4 -O1 -mmcu=attiny13        --> gleich
48
avr-gcc-4.6.4 -O1 -mmcu=atmega1280      --> gleich
49
avr-gcc-4.6.4 -O2 -mmcu=attiny13        --> gleich
50
avr-gcc-4.6.4 -O2 -mmcu=atmega1280      --> gleich
51
avr-gcc-4.6.4 -O3 -mmcu=attiny13        --> gleich
52
avr-gcc-4.6.4 -O3 -mmcu=atmega1280      --> gleich
53
avr-gcc-4.6.4 -Os -mmcu=attiny13        --> gleich
54
avr-gcc-4.6.4 -Os -mmcu=atmega1280      --> gleich
55
56
avr-gcc-4.7.4 -O0 -mmcu=attiny13        --> gleich
57
avr-gcc-4.7.4 -O0 -mmcu=atmega1280      --> gleich
58
avr-gcc-4.7.4 -O1 -mmcu=attiny13        --> gleich
59
avr-gcc-4.7.4 -O1 -mmcu=atmega1280      --> gleich
60
avr-gcc-4.7.4 -O2 -mmcu=attiny13        --> gleich
61
avr-gcc-4.7.4 -O2 -mmcu=atmega1280      --> gleich
62
avr-gcc-4.7.4 -O3 -mmcu=attiny13        --> gleich
63
avr-gcc-4.7.4 -O3 -mmcu=atmega1280      --> gleich
64
avr-gcc-4.7.4 -Os -mmcu=attiny13        --> gleich
65
avr-gcc-4.7.4 -Os -mmcu=atmega1280      --> gleich
66
67
avr-gcc-4.8.3 -O0 -mmcu=attiny13        --> gleich
68
avr-gcc-4.8.3 -O0 -mmcu=atmega1280      --> gleich
69
avr-gcc-4.8.3 -O1 -mmcu=attiny13        --> gleich
70
avr-gcc-4.8.3 -O1 -mmcu=atmega1280      --> gleich
71
avr-gcc-4.8.3 -O2 -mmcu=attiny13        --> gleich
72
avr-gcc-4.8.3 -O2 -mmcu=atmega1280      --> gleich
73
avr-gcc-4.8.3 -O3 -mmcu=attiny13        --> gleich
74
avr-gcc-4.8.3 -O3 -mmcu=atmega1280      --> gleich
75
avr-gcc-4.8.3 -Os -mmcu=attiny13        --> gleich
76
avr-gcc-4.8.3 -Os -mmcu=atmega1280      --> gleich
77
78
avr-gcc-4.9.1 -O0 -mmcu=attiny13        --> gleich
79
avr-gcc-4.9.1 -O0 -mmcu=atmega1280      --> gleich
80
avr-gcc-4.9.1 -O1 -mmcu=attiny13        --> gleich
81
avr-gcc-4.9.1 -O1 -mmcu=atmega1280      --> gleich
82
avr-gcc-4.9.1 -O2 -mmcu=attiny13        --> gleich
83
avr-gcc-4.9.1 -O2 -mmcu=atmega1280      --> gleich
84
avr-gcc-4.9.1 -O3 -mmcu=attiny13        --> gleich
85
avr-gcc-4.9.1 -O3 -mmcu=atmega1280      --> gleich
86
avr-gcc-4.9.1 -Os -mmcu=attiny13        --> gleich
87
avr-gcc-4.9.1 -Os -mmcu=atmega1280      --> gleich

Durchgenudelt mit diesem Skript:
1
#!/bin/sh
2
3
for gcc in /usr/local/avr/bin/avr-gcc-[0-9]*; do
4
  for opt in 0 1 2 3 s; do
5
    for mcu in attiny13 atmega1280; do
6
      cmd="$(basename $gcc) -O$opt -mmcu=$mcu"
7
      for sel in 0 1; do
8
        $cmd -x c -DSEL=$sel -S -o test$sel.s - <<EOF
9
#include <avr/io.h>
10
#include <inttypes.h>
11
12
uint16_t blink=24;
13
14
int main()
15
{
16
#if SEL
17
  if(--blink == 0 ){
18
    PORTB = PINB ^ ( 1 << PB0 );
19
    blink=24;
20
  }
21
#else
22
  if( ((uint16_t) --blink) == 0 ){
23
    PORTB = PINB ^ ( 1 << PB0 );
24
    blink=24;
25
  }
26
#endif
27
}
28
EOF
29
      done
30
      echo -ne "$cmd\t--> "
31
      if diff test{0,1}.s > /dev/null; then
32
        echo gleich
33
      else
34
        echo verschieden
35
      fi
36
    done
37
  done
38
  echo
39
done

@Jörg:

Folgendes
1
    PORTB = PINB ^ ( 1 << PB0 );

tut nicht immer das, was du damit vermutlich bezweckst, nämlich PORTB0
toggeln und sonst nichts. Wenn nämlich irgendein Pin von Port B als
Eingang genutzt wird, dann wird mit der obigen Anweisung je nach
Eingangspegel der Pullup-Widerstand für diesen Eingang aktiviert bzw.
deaktiviert, was wahrscheinlich nicht beabsichtig ist.

Besser:
1
    PORTB = PORTB ^ ( 1 << PB0 );

Noch besser:
1
    PORTB ^= 1 << PB0;

Falls der von dir eingesetzte AVR ein etwas neuerer ist, der über das
Pin-Toggle-Feature verfügt, noch besser:
1
    PINB |= 1 << PB0;

: Bearbeitet durch Moderator
von Daniel V. (danvet)


Lesenswert?

Johann L. schrieb:
> Daniel V. schrieb:
>> Ich könnte mir vorstellen, dass der Compiler optimiert.
>> Da nur 0..24 als Wert vorkommt, [...]
>
> Diese Annahme ist falsch, bzw. ein Compiler, der so eine Annahme oder
> darauf basierende Optimierungen macht, ist nicht korrekt.
>
> Beim Aufruf von main ist der Wert der Variablen nämlich nicht bekannt:
> Ein anderes Modul könnte Code vor main ausführen und blink auf einen
> anderen Wert setzen.

Prinzipiell hast du Recht.
Dennoch, so wie es da steht, ohne sonstige Funktionen etc. könnte ich 
sogar noch mehr optimieren und sagen: blink wird NIE 0, also kann ich 
alles weglassen. Es fehlt nämlich die while(1)-Schleife.

von Jörg E. (jackfritt)


Lesenswert?

Ich muss mich entschuldigen. Der gepostete Code funktioniert bei beiden 
Varianten.

Ich denke es liegt mal wieder zu 100% am Typ vor der Kiste.
Ich kann den Fehler nicht mehr reproduzieren.
Sorry fürs Steinewerfen. Ihr dürft jetz draufhauen :)

von Tassilo (Gast)


Lesenswert?

Yalu X. schrieb:
> Falls der von dir eingesetzte AVR ein etwas neuerer ist, der über das
> Pin-Toggle-Feature verfügt, noch besser:
>     PINB |= 1 << PB0;

Bloss nicht, da toggeln u.U. mehr Pins als du willst. Richtig ist
1
PINB = 1<<PB0;
Da bin ich auch schon drauf reingefallen, und man sieht es erst beim 
100. Drueberlesen, da man ja darauf konditioniert ist, bei einer 
Operation auf nur einem Portbit irgendwelche & und | zu sehen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Tassilo schrieb:
> Bloss nicht, da toggeln u.U. mehr Pins als du willst. Richtig ist
>  PINB = 1<<PB0;

Das geht auch, erfordert aber zwei Maschineninstruktionen statt einer.

Dieses
1
    PINB |= 1 << PB0;

sieht zwar auf den ersten Blick falsch aus, ist es aber nicht, da es vom
Compiler in ein SBI umgesetzt wird. Auch das SBI sieht an dieser
Stelle falsch aus (da man dahinter einen Read-Modify-Write-Ablauf
vermutet), ist es aber nicht. In den Datenblättern der entsprechenden
AVRs wird explizit der SBI-Befehl als einen Möglichkeit für die
Toggle-Funktion genannt.

: Bearbeitet durch Moderator
von Tassilo (Gast)


Lesenswert?

Gerade nachgesehen, hast recht, falsche Erinnerung. Im Problemfall 
wurden bei mir auch mehrere Bits gleichzeitig getoggelt, dann wird da 
wohl kein SBI mehr draus. Ich sollte nix schreiben ohne nochmals ins 
Datenblatt zu schauen :-/

von Rolf Magnus (Gast)


Lesenswert?

Johann L. schrieb:
> Daniel V. schrieb:
>> Ich könnte mir vorstellen, dass der Compiler optimiert.
>> Da nur 0..24 als Wert vorkommt, [...]
>
> Diese Annahme ist falsch, bzw. ein Compiler, der so eine Annahme oder
> darauf basierende Optimierungen macht, ist nicht korrekt.
>
> Beim Aufruf von main ist der Wert der Variablen nämlich nicht bekannt:
> Ein anderes Modul könnte Code vor main ausführen und blink auf einen
> anderen Wert setzen.

In C gibt es offiziell keinen Code vor main().

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> In C gibt es offiziell keinen Code vor main().

Für nicht-hosted Programme schon:

> The name and type of the function called at program startup
> in a freestanding environment [is implementation defined].

von Stefan F. (Gast)


Lesenswert?

So kann man code vor der main() ausführen:
1
void my_init() __attribute__ ((naked))  __attribute__ ((section (".init5")));
2
3
void my_init() {
4
   ...
5
}
6
7
void main() {
8
   ...
9
}

Geht auch, wenn die my_init() funktion in einer anderen Datei liegt, als 
main().

von Jörg E. (jackfritt)


Lesenswert?

@Yalu
Vielen Dank für den Hinweis. In meinem Fall nutze ich nur den tiny85 und 
der hat nur einen Port wo ich ein paar Pins auf Ein bzw. Ausgang 
geschaltet habe. Ich sollte
meine alten Code mal danach absuchen.

Woran erkenne ich die Unterstützung der neuen Toggle Feature?
Im Datenblatt zu finden?
Ich denke der Tiny ist alt wird wohl nur bei xmega etc geben?

Danke auch an den Rest für die Hilfe.

von Rolf M. (rmagnus)


Lesenswert?

Jörg Esser schrieb:
> Woran erkenne ich die Unterstützung der neuen Toggle Feature?
> Im Datenblatt zu finden?

Ja.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Jörg Esser schrieb:
> Woran erkenne ich die Unterstützung der neuen Toggle Feature?

Ganz so neu ist das auch wieder nicht.

> Im Datenblatt zu finden?

Ja. Bei denen, die toggeln können, findet sich dieser kurze Abschnitt im
Datenblatt:
1
Toggling the Pin
2
3
Writing a logic one to PINxn toggles the value of PORTxn, independent on
4
the value of DDRxn. Note that the SBI instruction can be used to toggle
5
one single bit in a port.


> Ich denke der Tiny ist alt wird wohl nur bei xmega etc geben?

Doch, der ATtiny85 ist relativ neu und hat dieses Feature, der ältere
ATtiny13 aber auch schon. Ich glaube sogar, das gilt für alle ATtiny,
die derzeit hergestellt werden.

von Vim! (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Das bezog sich einzig auf unseren Linuxfreund, der hier mit seinem vim
> angeben wollte.

Achje.
Ich habe lediglich andeuten wollen, dass es Gang und Gäbe ist Code mit 
#if 0 auszukommentieren. Denn sogar gängige Editoren (Ja Editoren) 
unterstützen das.
Du bist hier derjenige, der einen Linux-Flame draus macht.

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.