Forum: Gesperrte Threads Warum heutige C-Programmierer so ineffizient sind!


von tropf (Gast)


Lesenswert?

Heute: "while (1)" braucht 9 Tastenanschläge.
Gestern: "for (;;)" braucht nur 8.

: Verschoben durch User
von nocheinGast (Gast)


Lesenswert?

Was willst du uns damit sagen? Schließt du wirklich grade von der Größe 
des Quellcodes auf die Effizienz des Programms?

von Werner P. (Gast)


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 ;-)

von Floh (Gast)


Lesenswert?

Das ist schreibeffizient, aber so nicht wartbar:
http://nanochess.110mb.com/chess3.html
:-)

von Rolf Magnus (Gast)


Lesenswert?

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.

von Patrick-Oliver S. (patrick-oliver)


Lesenswert?

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.

von Christian B. (casandro)


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.

von Rolf Magnus (Gast)


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.

von (prx) A. K. (prx)


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.

von Christian B. (casandro)


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.

von Jens (Gast)


Lesenswert?

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...

von Karl H. (kbuchegg)


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.

von P. S. (Gast)


Lesenswert?

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...

von Rosa-Kleidchen (Gast)


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

von Karl H. (kbuchegg)


Lesenswert?

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.

von ♪Geist (Gast)


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.

von P. S. (Gast)


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 :-)

von Klaus W. (mfgkw)


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" :-)

von moep (Gast)


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

von (prx) A. K. (prx)


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.