die finden das irgendwie lustig.
Kenne da einige Programmierer die Zeit damit verbringen möglichst viel
Code in eine Zeile zu kompirimieren.
Und dann kann man sich anhören: Schau mal wie kurz mein Code ist.
Na ja, jedem das seine ;-)
Floh schrieb:> Das ist schreibeffizient
Vielleicht auf die Zahl der Tastenanschläge bezogen, aber auf die Zeit
sicher nicht. Das tippt man nicht einfach mal so runter.
Ich zähle mich gerne zu solchen Leuten ("for(;;)" braucht nur 7).
Die meisten Ideen sind zwar nicht brauchbar, aber hin und wieder tauchen
interessante Lösungsansätze auf.
Also zumindest bei guten Compilern gilt, dass man ihm durchaus zumuten
kann, solche Trivialsachen zu optimieren:
http://media.ccc.de/browse/conferences/camp2007/cccamp07-en-1952-Know_your_compiler.html
Die Probleme bei C liegen ganz wo anders. Zum Beispiel darin, dass eine
Funktion mehrere Rücksprungadressen haben kann.
Beispiel:
void irgendwas(){
...
}
int main(){
a();
b();
irgendwas();
c();
d();
e();
}
Da kann der Compiler nicht bestimmen, wohin "irgendwas" zurückspringt,
da in "irgendwas" die Rücksprungadresse geändert werden kann. (machen
sehr viele C-Programmierer!) Somit müssen bei ISRs alle Register
gespeichert werden.
Patrick-Oliver Scheinert schrieb:> Ich zähle mich gerne zu solchen Leuten ("for(;;)" braucht nur 7).
Ich bevorzuge auch "for(;;)", aber aus anderen Gründen.
Christian Berger schrieb:> Beispiel:>> void irgendwas(){> ...> }>> int main(){> a();> b();> irgendwas();> c();> d();> e();> }>> Da kann der Compiler nicht bestimmen, wohin "irgendwas" zurückspringt,> da in "irgendwas" die Rücksprungadresse geändert werden kann.
Höchstens wenn du deinen Stack zerschießt.
> (machen sehr viele C-Programmierer!)
Echt?
> Somit müssen bei ISRs alle Register gespeichert werden.
Bei einer ISR müssen alle Register gespeichert werden, wenn sie externe
Funktionen aufruft (und nur dann), weil der Compiler dann nicht weiß,
welche Register diese Funktionen intern benutzen.
Aber ISRs gibt es in der C-Spec sowieso nicht, genauso wie Register.
Christian Berger schrieb:> Da kann der Compiler nicht bestimmen, wohin "irgendwas" zurückspringt,> da in "irgendwas" die Rücksprungadresse geändert werden kann. (machen> sehr viele C-Programmierer!)
Hättest Du bitte ein Beispiel dafür?
Einen vorgesehenen Weg gibt es für die Änderung der Rücksprungadresse
nicht. Zwar machen das zwar tatsächlich viele Programmierer, allerdings
eher unfreiwillig in Form von Buffer Overflows.
A. K. schrieb:> Einen vorgesehenen Weg gibt es für die Änderung der Rücksprungadresse> nicht. Zwar machen das zwar tatsächlich viele Programmierer, allerdings> eher unfreiwillig in Form von Buffer Overflows.
Sag mir mal eines, wenn Buffer Overflows seit Jahrzehnten bekannt sind,
und ein Programmierer programmiert so was, wie willst Du feststellen, ob
er das mit Absicht oder aus Versehen gemacht hat? Wie soll das der
Compiler feststellen? Somit muss der Compiler auf der sicheren Seite
sein, und alle Register bei einer ISR weg speichern.
Nebenbei gibts natürlich einen definierten Weg die Rücksprungadresse zu
überschreiben. Man greift auf ein zu hohes Element eines lokalen Arrays
zu. Der Offset den man braucht hängt natürlich vom Compiler ab, aber C
war ja noch nie portabel. Der Wertebereich eines int hängt ja auch vom
Compiler und der Plattform ab.
Naja, seit ich C kenne, nehme ich (wieder) Assembler.
Das gilt jetzt zwar nur für uC, aber mit C habe ich immer den Eindruck,
der Controller macht was er will...
Christian Berger schrieb:> Nebenbei gibts natürlich einen definierten Weg die Rücksprungadresse zu> überschreiben.
definiert würde ich das nicht nennen.
Es gibt auch Prozessoren, die den Callstack vom Datenstack streng
getrennt haben.
Nur weil etwas auf deinem Prozessor genau so funktioniert, heißt das
noch lange nicht, dass das in C so vorgesehen ist. Als Faustregel kann
man sagen: Alles was auch nur irgendwie nach Hardwareabhängigkeit
stinkt, ist von C nicht definiert, sondern es wird dem konkreten
Compiler überlassen, wie er das implementiert. Das hat Nachteile, weil
einige Sachen ganz einfach nicht so streng definiert sind, wie man sich
das als Anwendungsprogrammierer gerne wünschen würde. Hat aber auch
Vorteile, weil dann ein Compiler nicht esoterische Features eines
anderen Prozessors aufwändig nachbilden muss sondern sich ganz darauf
konzentrieren kann, seinen Zielprozessor möglichst gut zu benutzen.
Der C Standard definiert, wie sich ein Programm verhalten muss, nicht
jedoch wie dieses Verhalten zu implementieren ist.
Und C Programme sind zum größten Teil deswegen so ineffizient, weil
der/die Programmierer ihr Handwerkszeug nicht mehr von der Pieke auf
lernen wollen. Schau dich hier im Forum um. Auf jede 3.te C Frage müsste
man im Grunde antworten: Kauf dir ein C-Buch, das steht da alles
drinnen.
Jens schrieb:> Das gilt jetzt zwar nur für uC, aber mit C habe ich immer den Eindruck,> der Controller macht was er will...
Komisch, ich nehme C++ und der Controller macht, was ich will...
Oh Gott,
was ist denn hier los! Gibt es keine Informatiker???
Ob Assembler oder C ist keine Frage der Ausführungsgeschwindigkeit
sondern der Verfügbarkeit. Wenn es für ein algorithmisches Problem nur
einen Assembler gibt, muss man den nehmen, ansonsten nie wieder!
Aus objektiver Algorithmus-Sicht ist - mit kleinen zu vernachlässigenden
Einschränkungen - der Geschwindigkeitsaufwand von C oder Assembler
konstant O(1)!
> (machen sehr viele C-Programmierer!)
Das glaube ich nicht. Ich bin nunmehr seit 20 Jahren mit C unterwegs und
ich kenne keinen, der ernsthaft die Rücksprungadresse innerhalb der
Funktion verändert. In C ist das möglich, aber auch in anderen
imperativen Programmiersprachen.
Hier reden viele vom C-Standard. Welcher denn? K&R-C?? ANSI-C?? ISO-C??
C99?? Whatever-C???
Rosa
Rosa-Kleidchen schrieb:> Hier reden viele vom C-Standard. Welcher denn? K&R-C?? ANSI-C?? ISO-C??> C99?? Whatever-C???
C99 ist der letzte ISO/ANSI - C Standard.
Eventuell kann man noch die C-Version von davor nehmen, in den C
Kernbereichen hat sich da ja nichts geändert. Aber K&R-C ist schon lange
tot, rest in peace but please rest.
tropf schrieb:> Heute: "while (1)" braucht 9 Tastenanschläge.> Gestern: "for (;;)" braucht nur 8.
Was hat das effiziente Programmieren mit Anzahl der Tastenschläge zu
tun?
Wer sagt, dass heute niemand for(;;) genutzt?
Effizient programmieren, kann auch 20 Zeilen Code/ Tag bedeuten, wenn
man durch die Programmierung klaren, übersichtlichen, effizienten und
möglichst fehlerfreien Code schafft.
Rosa-Kleidchen schrieb:> Oh Gott,>> was ist denn hier los! Gibt es keine Informatiker???
Du uebersiehst, dass das hier kein Informatiker-Forum ist, sondern ein
Mikrocontroller-Forum. Hier gibt es also tatsaechlich sehr wenige
Informatiker. Das merkt man spaetestens dann, wenn wieder Jemand 1000
Zeilen als "grosses Programm" verkaufen will :-D
> Das glaube ich nicht. Ich bin nunmehr seit 20 Jahren mit C unterwegs und> ich kenne keinen, der ernsthaft die Rücksprungadresse innerhalb der> Funktion verändert.
Siehe oben :-)
Rosa-Kleidchen schrieb:> Ich bin nunmehr seit 20 Jahren mit C unterwegs und> ich kenne keinen, der ernsthaft die Rücksprungadresse innerhalb der> Funktion verändert.
naja, gelegentlich macht mal jemand ein immerhin legales
setjmp()+longjmp().
Ob man das empfehlen will, steht auf einem anderen Blatt.
Karl Heinz Buchegger schrieb:> Christian Berger schrieb:>>> Nebenbei gibts natürlich einen definierten Weg die Rücksprungadresse zu>> überschreiben.>> definiert würde ich das nicht nennen.
Vielleicht immerhin "reproduzierbar" :-)
> Heute: "while (1)" braucht 9 Tastenanschläge.> Gestern: "for (;;)" braucht nur 8.
Super Sache...
Und ich benutze für oft genutzte Passagen die Makrotasten auf meiner
Tastatur und brauche somit nur einen einzigen Tastenanschlag.
Bin ich jetzt hypereffizient, hab' das System überlistet und darf mich
zurücklehnen? :D
Christian Berger schrieb:> Somit muss der Compiler auf der sicheren Seite> sein, und alle Register bei einer ISR weg speichern.
Der Compiler muss undefiniertes Verhalten nicht berücksichtigen.
Register sichert er in einer ISR je nachdem ob sie verwendet werden,
wenn er das weiss, oder mindestens alle temporären Register, wenn er das
aufgrund von Funktionsaufrufen nicht weiss. Aber vorsätzliche Buffer
Overflows wird er dabei nicht berücksichtigen.
Gibts tatsächlich eine signifikaten Anzahl Programmierer, die
vorsätzlich Buffer Overflows verwenden um die Rücksprungadresse ihres
eigenen Programms zu manipulieren? Ich kenne das nur als unfreiwillige
Kooperation. Der eine baut unabsichtlich oder fahrlässig den Buffer
Overflow rein und der andere (Black Hat) nutzt ihn aus.
> Nebenbei gibts natürlich einen definierten Weg die Rücksprungadresse zu> überschreiben.
Nein, den gibt es nicht, weil dieser Weg vollständig undefiniert ist.
Die Rücksprungadresse muss auch nicht auf dem Stack liegen. Der Umstand,
dass es bei einer bestimmten Plattform mit einer bestimmten
Compilerversion funktioniert, macht es nicht zum definierten Verhalten.