array = array ??



  • Original erstellt von HumeSikkins:
    Selbst gute Bücher von 1970 (da gab es meines Wissens noch keinen OOP-Hype) sagen: "Duplication is the root of all evil". Und 250-mal die selbe Schleife in einem Programm zu schreiben ist definitiv "duplication". Länger, fehleranfälliger, schlechter wartbar (da weniger kommunikativ) als eine simple Funktion.

    Es ist weniger fehleranfällig Code in Funktionen zu schreiben, als anderswohin? Code wir besser wartbar, wenn ich ihn in eine Funktion packe? Und kürzer wird es auch noch? Ungeheuer praktisch solche Funktionen. WashatdasdenmitdemThemazutundasichangesprochenhatte?

    Eine Lösung, die komplexer ist als sie sein müsste ist schlecht, können wir uns darauf einigen? Ein so seltenes Problem wie strcpy oder copy braucht man aber vielleicht 2x pro Projekt (ich habe hier man einige Quelltexte analysiert und von einigen wenigen Menschen, die »strcpy(dst, "")« schreiben, abgesehen kam strcpy 50 mal in ~78000 Zeilen Code vor. Verteilt auf die 10 Projekte bleiben 5 strcpy-Aufrufe pro Projekt, die ich aber hier nur in 2 Projekten wiederfinde.) So etwas ist ist überflüssig, weil 'normale' C++-Programme ungefähr nur aus for-Schleifen bestehen. Der aufmerksame Leser stellt fest, dass for also häufig getippt wird und erkennt die 'Duplicaltion'?

    Original erstellt von klausmuell:
    [Templates]
    also laufzeitkosten haben sie schonmal nicht.

    Ja. Aber abgefahrene Compile-Zeiten, bei mir bekannten Compilern.

    wer sollte diese entscheidungen denn sonst treffen?

    Jemand der das Problem kennt. Also der Programmierer.

    memcpy [...] macht bei kleinen arrays und bekannter fester größe ne zuweisung, später evtl nur repne mov und noch später total tolle auf bestes alignment hin getrimmte duff-devices?

    Das ist mir egal. Wenn es darauf ankommt, dann sollte man das Programm direkt in Asm hacken.



  • Es ist weniger fehleranfällig Code in Funktionen zu schreiben, als anderswohin?

    Aber 100%tig. Den Code für eine Funktion schreibe ich *einmal* und nicht tausendmal an zweihundert verschiedenen Stellen. Eine Funktion ist auch leichter zu testen als keine Funktion. Auch das reduziert die Wahrscheinlichkeit von Fehlern.

    Code wir besser wartbar, wenn ich ihn in eine Funktion packe?

    Aber 100%tig. Code wird übersichtlicher, leichter verständlich, kommunikativer.

    Und kürzer wird es auch noch?

    Ist das eine Art Quiz? Ich würde mal sagen, dass Code in den meisten Fällen durch die Verwendung von Funktionen kürzer wird. Vorallem, da ein Funktionsaufruf in einer Sprache wie C++ auf Quellcodeebene keinen wirklichen overhead hat.

    Eine Lösung, die komplexer ist als sie sein müsste ist schlecht, können wir uns darauf einigen?

    Keine Ahnung. Wohl eher nicht. Denn eine Lösung die für dich komplexer ist, scheint für mich *deutlich* einfacher und bestimmt gibt es auch Situationen wo dies genau andersherum ist.

    Das ist genau der Grund, weshalb ich eine Diskussion für sinnlos halte. Ich kann mich in dieser Sache mit dir auf keinen gemeinsamen Ausgangspunkt einigen. Das Funktionen sinnvoll sind ist für mich so in Steingemeißelt, wie es die zehn Gebote einmal waren. Mein Geist ist nicht flexibel genug, als das ich da über Alternativen nachdenken könnte. Und mit jedem weiterem Buch über Softwaredesign/technik das ich lese wird mein Geist in dieser Richtung unflexibler.

    [ Dieser Beitrag wurde am 22.03.2003 um 20:29 Uhr von HumeSikkins editiert. ]



  • Jemand der das Problem kennt. Also der Programmierer.

    hmm in der regel wird der compiler trozdem mehr ahnung von optimierung haben als der programmierer selbst...
    was auf nem intel x86 system gross ist ist vielleicht auf nem Vektorrechner garnimmer so gross und dann weis der entsprechende compiler sicher besser was zu tun ist als ich...



  • Original erstellt von HumeSikkins:
    Den Code für eine Funktion schreibe ich *einmal* und nicht tausendmal an zweihundert verschiedenen Stellen.

    Ich schreibe Code generell immer in Funktionen rein. Ich habe festgestellt, dass der Compiler das sonst nicht übersetzt.

    Eine Funktion ist auch leichter zu testen als keine Funktion. Auch das reduziert die Wahrscheinlichkeit von Fehlern.

    Nein. Es erhöht vielleicht höchstens die Wahrscheinlichkeit, einen Fehler zu finden; es hindert bestimmt nicht daran Fehler zu machen, denn (relevante) Fehler entstehen bei mir im Kopf und nicht bei der Übermittlung vom Gehirn zu den Händen. So meine Erfahrung.

    Ist das eine Art Quiz?

    Nein.

    Ich kann mich in dieser Sache mit dir auf keinen gemeinsamen Ausgangspunkt einigen.

    Das wundert mich eigentlich nicht wirklich: wir reden von absolut verschiedenen Dingen. Ich rede davon, dass man nicht benötige Abstraktion zu entfernen hat um dem realen Problem näher zu kommen (nicht mehr auf verketteten Listen, sondern auf Netzwerkadressen zu operieren zB). Und Du willst Quelltext in Funktionen schreiben. Kein Widerspruch. Ich hatte nicht vorgeschlagen, den gesamten Quelltext in die erste Zeile der main-Funktion zu schreiben, nur aus as bestehende Bezeichner zu verwenden oder keine Templates mehr zu benutzten auch wenn Du mir das ständig in den Mund legen willst.

    Original erstellt von japro:
    in der regel wird der compiler trozdem mehr ahnung von optimierung haben als der programmierer selbst...

    Kommt drauf an, was man unter Optimierung versteht. Ob ich nun Shiftoperatoren oder Multiplikationen verwende kann von miraus gerne der Compiler entscheiden. Vom algorithmenverbessern soll er aber bitte die Finger lassen. Und diese Entscheidung trifft der Programmierer aufgrund irgendwelcher Daten die ihm aber nicht dem Compiler vorliegen.

    was auf nem intel x86 system gross ist ist vielleicht auf nem Vektorrechner garnimmer so gross

    Code wird auch 'in der Regel' nicht kontextfrei geschrieben und dann für alle Systeme einmal übersetzt. Er wird dafür geschrieben um ein real existierendes Problem zu lösen. Da C (und bei C++ ist das nicht wirklich anders) eine maschinennahe Sprache ist, sollte der Programmierer das System für das er entwickelt _wirklich gut_ kennen (wenn das Programm in Bereichen eingesetzt wird, wo die Laufzeit relevant ist).

    [ Dieser Beitrag wurde am 23.03.2003 um 01:04 Uhr von Daniel E. editiert. ]



  • Ich schreibe Code generell immer in Funktionen rein. Ich habe festgestellt, dass der Compiler das sonst nicht übersetzt

    Ok. Scheinbar haben wir das Niveau gewechselt.

    Kein Widerspruch. Ich hatte nicht vorgeschlagen, den gesamten Quelltext in die erste Zeile der main-Funktion zu schreiben, nur aus as bestehende Bezeichner zu verwenden oder keine Templates mehr zu benutzten auch wenn Du mir das ständig in den Mund legen willst.

    Erstens hatte ich das nicht angenommen und zweitens versuche ich nicht dir irgendwas in den Mund zu legen. Zumindest nicht bewusst. Du hast geschrieben, dass du sowas wie strlen, strcpy, memcpy, copy & Freunde als Funktionen für sinnlose Abstraktion hälst. Ich bin da völlig anderer Meinung. Mir ist allerdings nicht klar, wo ich dir mit meinen Postings irgendwas üer Templates oder Quelltext in einer Zeile in den Mund lege.



  • Original erstellt von HumeSikkins:
    Du hast geschrieben, dass du sowas wie strlen, strcpy, memcpy, copy & Freunde als Funktionen für sinnlose Abstraktion hälst.

    Ja. Weil in 'gängigen Programmen' diese Operationen ~1x gebraucht werden.
    Ich abstrahiere doch keine Datenstrukturen nur um sie dann nicht zu verwenden.



  • Ja. Weil in 'gängigen Programmen' diese Operationen ~1x gebraucht werden.

    Wie arbeitet man in C mit Strings ohne strcpy,strcmp, strlen und co zu verwenden?

    Und was heißt gängige Programme? Ich habe letztens zwei Wochen lang an Parallelen-Simulations-Programmen (Bereich Physik) gearbeitet. Dort hatte ich teilweise in jeder Funktion zwei Aufrufe von memset, memcmp oder memcpy.

    Ich abstrahiere doch keine Datenstrukturen nur um sie dann nicht zu verwenden

    Ne. Das würde ich auch als unnötige Komplexität bezeichnen. Aber wie bereits angedeutet: Die genannten Funktionen benutzt man meines Wissens nach doch sehr häufig (allein schon, weil es Standardfunktionen sind). Klar, Funktionen sind keine Datenstrukturen, aber ich weiß sonst nicht auf was sich deine Aussage bezieht.



  • Original erstellt von Daniel E.:
    Da C (und bei C++ ist das nicht wirklich anders) eine maschinennahe Sprache ist, sollte der Programmierer das System für das er entwickelt _wirklich gut_ kennen (wenn das Programm in Bereichen eingesetzt wird, wo die Laufzeit relevant ist).

    Lächerlich!
    Natürlich soll er das System gut kennen.
    Aber das als Argument dafür einzusetzen, daß er dann per Hand optimieren soll, entbehrt doch jeder Logik. Ein C++-Programmierer muß in den seltendsten Fällen zur Assembler-Trickkiste greifen oder gar den Lötkolben benutzen. Er muß es nur können, umd dann mal über mal festzustellen, daß C++ keine Abstraktionskosten hat. Und typischerweise werden die Progs lahm, weil der Programmierer NICHT die eingebauten Sachen verwendet, sondern selbst ausgedachte Optimierungen (mal davon ausgehend, daß er gute Algorythmen verwendet).



  • Original erstellt von HumeSikkins:
    Wie arbeitet man in C mit Strings ohne strcpy,strcmp, strlen und co zu verwenden?

    Die Länge berechnet sich bei unbekannten Strings 1x oder man nutzt die Puffergröße (die man sich optimaler Weise gemerkt hat). Wenn man nicht 2 potentiell unendlich lange Stringws miteinander vergleichen will, dann natürlich 'if (*a == *b && a[1] == b[1] ...)'. Kopien erzeugt man wirklich nur, wenn man der Überzeugung ist, dass man mit dieser Kopie etwas wichtiges anfangen muss. Ich kopiere nicht aus Bequemlichkeit, »weil es dafür 'ne Funktion gibt«. Das macht man entgegen scheinbar anderslautenden Meinungen (aus gelesem Quelltext) nicht um einem Wert einen schönen Namen zu geben oder um es an eine Ausgabefunktion zu übergeben. Zugegebenermaßen: String-Handling ist in C ausgesprochen ekelhaft und zeitintensiv, so dass man vielleicht besser beraten ist im Allgemeinen zu Ada zu greifen.

    Und was heißt gängige Programme?

    Das mit dem ich so rumspiele. Systemprogrammierung und Netzwerkkrimskrams hauptsächlich (abzuglich Spaßprojekte die dann auch schon mal Benutztereingaben verarbeiten müssen ... :)).

    Klar, Funktionen sind keine Datenstrukturen, aber ich weiß sonst nicht auf was sich deine Aussage bezieht.

    Das war ein Beispiel.

    Original erstellt von klausmuell:
    Aber das als Argument dafür einzusetzen, daß er dann per Hand optimieren soll, entbehrt doch jeder Logik.

    Ja. Das hatte ich auch nie behauptet. Trotzdem ist es in wirklich zeitkritischen Umgebungen sinnvoll sich mal anzusehen, was der Compiler sich da so alles ausgedacht hat. Er muss nicht die anzahl der bewegten Elektronen bei einer Adition von Integerzahlen wissen, aber etwas Wissen über die Maschine schadet nicht, besonders weil der Compiler einen Ausdruck wie 'a = b; f(); b = c;' nicht trivial zu 'a = b; b = c; f();' umformen kann (auch wenn es die Semantik nicht verändert und zu wesentlich Schnellerem Code führt), weil f eine Funktion sein kann, die in einer anderen Übersetztungseinheit liegt. Hier stößt das schöne theoretische Modell vom Optimizer schon an seine Grenzen.

    [ Dieser Beitrag wurde am 23.03.2003 um 02:15 Uhr von Daniel E. editiert. ]



  • Original erstellt von Daniel E.:
    **Ja. Das hatte ich auch nie behauptet. Trotzdem ist es in wirklich zeitkritischen Umgebungen sinnvoll sich mal anzusehen, was der Compiler sich da so alles ausgedacht hat. Er muss nicht die anzahl der bewegten Elektronen bei einer Adition von Integerzahlen wissen, aber etwas Wissen über die Maschine schadet nicht, besonders weil der Compiler einen Ausdruck wie 'a = b; f(); b = c;' nicht trivial zu 'a = b; b = c; f();' umformen kann (auch wenn es die Semantik nicht verändert und zu wesentlich Schnellerem Code führt), weil f eine Funktion sein kann, die in einer anderen Übersetztungseinheit liegt. Hier stößt das schöne theoretische Modell vom Optimizer schon an seine Grenzen.
    **

    so klingt es super.
    volle zustimmung.

    ich vertraue auch nur deshalb auf diesen meinen bereits gezeigten coden, weil ich geschaut habe, welchen assembler-code der compiler draus macht. ich war stets sehr sehr zufrieden. ich mag sogar verallgemeinern, daß moderne compiler alle so gut wie die gcc sind (also die icc und der msvc auch). sie schlagen normalsterbliche handoptimierer beim takt-zählen und pipelinesfüllen in der tat. und das sorgt sogar (halau!) dafür, daß der normalsterbliche c++-progger (mit geringen asm-kenntnissen) den normalsterblichen asm-progger (mit geringen c++-kenntnissen) locker outpreformed (außer es ist ein prob, wo MMX oder so gut zieht und der compiler noch ahnungslos dhingehend ist (alle zur zeit, oder?)).



  • String-Handling ist in C ausgesprochen ekelhaft und zeitintensiv, so dass man vielleicht besser beraten ist im Allgemeinen zu Ada zu greifen.

    Einfach mal so die Sprache zu wechseln ist aber wohl auch nur in Spaßprojekten möglich 🙂

    Mal von der anderen Seite betrachtet: Wo liegt der Vorteil, wenn strlen, strcpy,memcpy usw. *keine* Funktionen wären?

    So wie ich das sehe:
    1. Der Code (den ich schreiben muss) wird nicht kürzer. Ich brauche für ein eigenes strlen inklusive Definition und Zuweisung der Ergebnisvariablen 28 Zeichen. Für den Aufruf der Funktion strlen 18. Für das Inkludieren des Headers kommen nochmal 19 Zeichen hinzu. Das sind aber einmalige kosten.

    Kürzer ist wahrscheinlich der Code, den der Compiler später sieht, da ja keine
    Standard-Header inkludiert werden müssen.

    2. Der Code wird nicht leichter zu verstehen, kommunikativer oder besser wartbar.
    Es gibt bestimmt Situationen in denen es diesbezüglich überhaupt keinen Unterschied zwischen Funktion vs. Nicht-Funktion gibt.
    Auf der anderen Seite:
    Ich wette mindestens einer wird beim Lesen von 1. feststellen, dass er ein kürzeres strlen hinbekommt. Nicht alle können C gleich gut. Die Wahrscheinlichkeit, dass ein Programm später fünf verschiedenen Schleifen für genau die gleiche Funktionalität beinhaltet ist meiner Meinung nach sehr groß.

    Eine Schleife ist erstmal nur eine Schleife. Es liegt an mir und meiner Erfahrung in eine Schleife Semantik reinzuinterpretieren. Das ist natürlich bei so einfachen Sachen ohne größere Probleme möglich.
    Auf der anderen Seite:
    Natürlich muss man auch eine Zeichenkette wie "strlen" erstmal interpretieren. Ich denke aber, dass dies auf jeden Fall einfacher ist. Es bedarf auf jeden Fall weniger Wissen dazu.

    3. Der Code wird nicht leichter zu testen.
    Habe ich nur einen Aufruf, ist der Testaufwand genau gleich. Habe ich aber 100 Aufrufe im gesamten Programm, wobei sich die Schleifen wegen 1. vielleicht auch noch leicht unterscheiden und entdecke ich einen Fehler, dann muss ich bei der Funktion diesen Fehler einmal ändern. Die Schleife muss ich aber 100 mal Suchen.

    4. Der Code wird nicht unbedingt schneller. Keine Ahnung, ob man bei solchen Funktionen noch irgendwas an Geschwindigkeit rausquetschen kann. Wenn das aber möglich ist, dann kann das ein Experte (derjenige der die std::-Funktionen schreibt) sicher besser als ein Blödbeutel wie ich. Erneut: Nicht alle können C gleich gut. Ich denke es wäre unfair anzunehmen, die restliche Welt hätte im Schnitt dein Expertenlevel.

    Zugegeben, die Implementation der genannten Funktionen mag trivial sein, dass ist in meinen Augen aber überhaupt kein Grund dafür auf die Abstraktion einer
    Funktion zu verzichten.
    Dinge wie das Bestimmen der Länge eines Strings sind für mich primitive, abgeschlossene Operationen und sollten in meinen Augen deshalb auch abstrahiert werden und überall zur Verfügung stehen.
    Wie man in meinen Postings nachlesen kann, sehe ich den Nachteil der Abstraktion solcher Funktionalität nicht. Ich sehe keine erhöhte Komplexität, gleichzeitig erhalte ich aber all die Vorteile die Abstraktion mit sich bringt.
    Durch die Verwendung einer Funktion kann ich mich auf das "was" konzentrieren ohne mir dabei Gedanken über das "wie" machen zu müssen. Bei der expliziten Schleife steht eindeutig der Algorithmus im Vordergrund. Nicht die eigentliche Funktionalität.

    Und zum Schluss habe ich noch eine Frage: Ab wann wird eine Abstraktion für dich sinnvoll? Am Beispiel: strcmp hälst du für sinnlos. Wie sieht es mit einem case-insensitiven Stringvergleich aus? Funktion oder nicht?



  • Original erstellt von HumeSikkins:
    4. Der Code wird nicht unbedingt schneller. Keine Ahnung, ob man bei solchen Funktionen noch irgendwas an Geschwindigkeit rausquetschen kann. Wenn das aber möglich ist, dann kann das ein Experte (derjenige der die std::-Funktionen schreibt) sicher besser als ein Blödbeutel wie ich. Erneut: Nicht alle können C gleich gut. Ich denke es wäre unfair anzunehmen, die restliche Welt hätte im Schnitt dein Expertenlevel.

    Bitte sachtsam als Argument verwendigen, da anderenfallsig der Stil den Bach runtergeht und zum Kindergartenstil wird und die Sprache wird folgen und sich Java annähern. Bitte C++ ne Sprache sein lassen, die ist sich wie Rennauto, und zwar mächtig UND schnell aber schwer zu beherrschigen.
    Tips, wie Speedgeile Freaks was machen sollten und wie man die Oberkomplexesten Komplexe baut, sind an sich direkt sachdienlicher. Da ist sich natürlich reinverpackt, daß der ganzige Kram sehr gut lesbar sein muß, sonst leiden Komplexität unmittlbar und Speed mittelbar, weil man an Komplexitätsgrenze ist und Algos nicht beschleunigen kann (oft gesehen habe lahmste asm-kutsche weil algo schwach).



  • Original erstellt von HumeSikkins:
    [quote]Am Beispiel: strcmp hälst du für sinnlos. Wie sieht es mit einem case-insensitiven Stringvergleich aus? Funktion oder nicht?

    Falsche Prämissen und falsche Fragen ;). Ich habe in meinen Programmen vielleicht einen strcmp-Aufruf. Wenn ich 200 habe, dann _mache_ ich dafür _natürlich_ eine Funktion -- ich bin jenau so gegen Codeverdoppelung wie Du, darum gehe ich auf deine Argumente nicht ein! --, aber derartige 10-Zeiler haben in der Standardbibliothek (!= irgendeine Bibliothek) nichts verloren. Da gehören Dinge rein, die ich nicht in 1 Minute ohne Nachzudenken portabel runtertippen kann. Wenigstens in C.

    Abstrakte Interfaces haben 'meiner Erfahrung nach' genau den Vorteil, dass jemand Low-Level-Spaß hinter Funktionen/ Klassen/ $sonstwas versteckt, wo jeder merkt, was sich dahinter versteckt. Dass das das Gegenteil von Abstraktion ist, sollte ersichtlich sein. Dieser Interfacemüll wird im Schnitt zu oft wieder neu 'geinterfacet' und am Schluss hat man aus 1000 Zeilen 10000 gemacht (und das ist gerade beim Warten von Software interessant zu sehen, wie jede Generation sich ihren Lieblingswrapper zusammenschustert ...).

    [ Dieser Beitrag wurde am 23.03.2003 um 13:31 Uhr von Daniel E. editiert. ]



  • @Daniel E.:
    kann es sein, dass du nur dein Umfeld siehst?

    Nur weil du strlen und Co quasi nie brauchst, so gibt es dennoch Leute die es oft brauchen.
    und strlen und Co kostet dir ja nichts, wenn du es nicht brauchst. (denn dann brauchst du <cstring> nicht einbinden)



  • Original erstellt von Shade Of Mine:
    **
    und strlen und Co kostet dir ja nichts, wenn du es nicht brauchst. (denn dann brauchst du <cstring> nicht einbinden)**

    Normalerweise wird immer die gesamte C Lib mitgelinkt. Also vielleicht keine Laufzeitkosten...



  • Original erstellt von Lars:
    Normalerweise wird immer die gesamte C Lib mitgelinkt. Also vielleicht keine Laufzeitkosten...

    bitte lösch deinen schlechten linker.



  • Original erstellt von Shade Of Mine:
    kann es sein, dass du nur dein Umfeld siehst?

    NATÜRLICH sehe ich immer nur mein Umfeld. Ich erlaube mir keine Urteile über Dinge, die ich nicht kenne (von Voruteilen, die wohl jeder irgendwie mit sich herumschleppt, weil er zu faul ist, sich mal mit einem Sachverhalt richtig auseinanderzusetzten, abgesehen).

    Nur weil du strlen und Co quasi nie brauchst, so gibt es dennoch Leute die es oft brauchen.

    Ja natürlich. 'Normalerweise' wird strlen ungefär so verwendet:

    char str[GENUG];
    
    get_irgendwoher(str);
    
    /* ... */
    int const sz = strlen(str);
    for (int i = 0; i < sz; ++i) {
      str[i] = foo(str[i]);
    }
    

    Alternativ kann man strlen gleich in den Schleifenkopf schreiben um einen Algorithmus mit bisher linearer Laufzeit in einen mit quadratischer zu verwandeln (wobei das dem Hörensagen nach manche Compiler optimieren)... 'Richtiger wäre' hier zB

    /* ... */
    char *p;
    
    p = str;
    while (*p) {
        *p = foo(*p);
        ++p;
    }
    

    Uswusf.


Anmelden zum Antworten