Warum heutige C-Programmierer so ineffizient sind!

Gast #2297727
Lesenswert?

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 ;-)
#2297752
Lesenswert?

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.
Gast #2297754
Lesenswert?

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.
#2297756
Lesenswert?

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.
#2297769
Lesenswert?

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.
#2297774
Lesenswert?

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.
Gast #2297792
Lesenswert?

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
Gast #2297806
Lesenswert?

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.
Gast #2297822
Lesenswert?

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 :-)
#2297919
Lesenswert?

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" :-)
Gast #2297933
Lesenswert?

> 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
#2298286
Lesenswert?

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.
Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.