Forum: Compiler & IDEs Warum Doppel-RET ?


von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Erstmal ein dickes Lob an die WINAVR-Entwickler.

Alles funktioniert 1A auch ohne jemals ein Make zu verwenden.

Und die Kodeeffizienz ist auch o.k.
Man darf nur nicht die Flashgröße einer Byte-Maschine (8051) mit einer
Wort-Maschine (AVR) in Bytes vergleichen, da kommt nur Mist raus. D.h.
von AT89C2051 nach AT90S2313 geht nun mal nicht.
Meine alten AT89C2051/4051 Programme kann ich jedoch bequem auf einen
ATMega8 umrubeln und gut is.


Nur manchmal kann ich was nicht nachvollziehen, daher meine Fragen.

1.
Im Anhang ist das Listing einer Funktion, wo am Ende 2* RET  steht.
Weiß einer vielleicht warum, ist dem Compiler ein RET etwa nicht sicher
genug ?

Das er RCALL+RET nicht nach RJMP optimiert kann ich ja noch verstehen,
aber das 2.RET ist schlichtweg unerreichbarer Code.


2.
warning: `irem' might be used uninitialized in this function

Gibt es ne Möglichkeit für Variablen diese Warnung abzuschalten ohne
diesen unnötig einen Wert zuweisen zu müssen.
Manchmal kann diese Warnung ja richtig sein, deshalb will ich sie nicht
global abschalten, sondern eben nur für bestimmte Variablen.


3.
ct1 = ct0 ^ ct1 & i;
Dieser Code erzeugt:

warning: suggest parentheses around arithmetic in operand of ^

Das verstehe ich nun überhaupt nicht, im C-Handbuch steht, & kommt vor
^ und er macht das ja auch richtig. Warum warnt er dann ?



Peter

von Stefan (Gast)


Lesenswert?

Ich habe früher den 8051 benutzt, und spätestens wenn man mehr als diese
256 Byte intern benutzte, reagierte das Grauen. Die Einzelbefehle mögen
länger sein, aber bei größeren Programmen wird der Code mit den ATmegas
wesentlich effizienter.
Bei meinen Programmen machen die Flash-Daten (Tabellen, Texte, Graphik,
etc.) meistens mehr als 60% der Größe aus. Die sind ja dann
CPU-unabhängig immer gleich gross.

> 2.
> warning: `irem' might be used uninitialized in this function
> Gibt es ne Möglichkeit für Variablen diese Warnung abzuschalten ohne
> diesen unnötig einen Wert zuweisen zu müssen.
> Manchmal kann diese Warnung ja richtig sein, deshalb will ich
> sie nicht global abschalten, sondern eben nur für
> bestimmte Variablen.

Wenn Du der Variable einen Wert zuweist, ohne sie zu benutzen, wird die
Zuweisung doch eh wegoptimiert. (So wie ich Dich kenne, hast Du die
Optimierung sicher eingeschaltet ;-) ).
Die Zuweisung macht Dir im Programm also nichts kaputt.

> 3.
> ct1 = ct0 ^ ct1 & i;
> Dieser Code erzeugt:
> warning: suggest parentheses around arithmetic in operand of ^
> Das verstehe ich nun überhaupt nicht, im C-Handbuch steht, &
> kommt vor ^ und er macht das ja auch richtig. Warum warnt er dann ?

Die Compiler-Macher gehen wohl davon aus, dass der Programmierer in den
meisten Fällen nicht das meinte, was der Compiler dann draus macht.
Deswegen ist es ja auch nur ne Warnung.

Stefan

von Joerg Wunsch (Gast)


Lesenswert?

> Im Anhang ist das Listing einer Funktion, wo am Ende 2* RET steht.
> Weiß einer vielleicht warum, ist dem Compiler ein RET etwa nicht
> sicher genug ?

Ein gcc optimiert zwar nicht schlecht, aber auch er ist natürlich nur
eine Maschine, somit kann er zuweilen eben Dinge nicht feststellen,
die dem menschlichen Auge völlig offensichtlich sind.  Typischerweise
ist in solchen Fällen das eine RET ein normales return am Ende der
Funktion, das andere in vorzeitiges Verlassen, das der Optimierer
angesetzt hat.

Eventuell bekommst Du für sowas auf der avr-gcc-Liste eine kompetente
Antwort.

> warning: `irem' might be used uninitialized in this function

> Gibt es ne Möglichkeit für Variablen diese Warnung abzuschalten

Nicht daß ich wüßte.

> warning: suggest parentheses around arithmetic in operand of ^

Du hast zwar Recht, daß die Operatorenreihenfolge in C passend
vorgeschrieben ist, aber selbst nach fast 15 Jahren C könnte ich Dir
nicht aus dem hut sagen, ob nun & oder ^ Vorrang hat -- so will der
Compiler Dir nur den freundlichen Hinweis geben, daß in diesem Falle
vielleicht die Klammern gar nicht so schlecht wären.

Wenn Dich die Warnung stört, müßtest Du sie mit -Wnoparentheses
loswerden können.

von Peter D. (peda)


Lesenswert?

@Stefan,

"aber bei größeren Programmen wird der Code mit den ATmegas
wesentlich effizienter."

Kann ich aber nicht bestätigen. Ich habe mal mein Schedulerbeispiel aus
der Codesammlung verglichen. Es ist ja doch ein längeres Stück Kode, so
daß sich ein guter Mix ergibt:

WINAVR:   564 Byte
Keil C51: 355 Byte

Ich hatte auch nicht den Eindruck, daß der WINAVR dabei besonders
umständlich vorgegangen wäre und in Assembler noch viel rauszuholen
ist.

Aber auch wenn man die Schedulerliste in andere Speicherbereiche legt,
steigt der Kodeverbrauch nur etwas an:

Keil C51, pdata segment: 358 Byte
Keil C51, xdata segment: 455 Byte


Deshalb bleibe ich dabei: Wenn ein 89C52 (8kB) zu 80% ausgelastet ist,
wird der Versuch, ihn in einen Mega8515 zu quetschen, oftmals in Frust
enden (zumindest bei meinem Programmierstil). Nimm einen Mega162 und
alles ist o.k.



Peter

von Stefan (Gast)


Lesenswert?

Hallo Peter,

ich mag nicht um jedes einzelne Byte feilschen. Bei den Projekten, die
ich auf dem 8051 gemacht habe, war der Stack im RAM > 256 Byte. Und das
sah RICHTIG ineffizient aus. Mag sein, dass der Keil-Compiler
mittlerweile da besser optimiert, aber in jedem Fall wird der Compiler
bei externem Stack auch heute noch ein Problem haben.

Es gibt sicherlich viele Projekte, die das nicht brauchen. Und auch
wenn Du ständig Portpins oder Bits schaltest, wird der 8051 besser
aussehen. Aber welche Programme dieser Klasse erreichen 8kb
Programmcode?

Der einzige Nachteil, den der ATmega vom 8051 geerbt hat, ist meiner
Meinung nach die unterschiedliche Adressierung von RAM, ROM und EEPROM.


Stefan

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.