Warum hat man den Rückgabewert von strcmp so dämlich gewählt?



  • char s1[] = "Hallo";
      char s2[] = "Hallo";
      strcmp(s1, s2); // strcmp liefert 0 zurück, wenn s1 und s2 gleich sind, was hier der Fall ist.
      // Aber
      if(0){
        printf("nada\n"); // wird nicht ausgeführt, weil für if() gilt*: true = 1 und false = 0.
      }
      // baut man also strcmp in if ein
      if(strcmp(s1, s2)){
        printf("nix da\n"); // dann wird der Code nicht ausgeführt, weil bei Gleichheit, also strcmp == true, als Rückgabewert 0 raus kommt und der ist für if ein false.
      }
      // man muss also die Ausgabe invertieren
      if(!strcmp(s1, s2)){
        printf("Jetzt gehts\n");
      }
    

    Frage, wer hat sich so einen Mist ausgedacht?

    Logisch wäre doch, dass strcmp true, also 1 zurückgibt, wenn die Strings gleich sind und false, also 0, wenn sie nicht gleich sind.
    Damit man das wieder schön in if() einbauen kann, ohne sich mit einem ! völlig verrenken zu müssen.

    Um am Kopf anzukommen, muss man also erst von Hinten aufzäumen, also vom Schwanz durch den Arsch um dann irgendwann am Kopf anzukommen. Völlig verquirlt.
    Wer zum Geier denkt sich so einen Mist aus? 😡

    * Genauer ist es natürlich für if(): true wenn != 0, aber das ist ein Nebenthema.


  • Mod

    Bevor du so etwas Mist nennst, hättest du vielleicht mal lesen sollen, was strcmp sonst noch so alles im Rückgabewert codiert. Oder was andere Funktionen der Standardbibliothek typischerweise von Vergleichsfunktionen erwarten. So hast du dich jetzt leider als völlig unqualifizierter Schreihals geoutet.



  • SeppJ schrieb:

    Bevor du so etwas Mist nennst, hättest du vielleicht mal lesen sollen, was strcmp sonst noch so alles im Rückgabewert codiert. Oder was andere Funktionen der Standardbibliothek typischerweise von Vergleichsfunktionen erwarten. So hast du dich jetzt leider als völlig unqualifizierter Schreihals geoutet.

    Schön, der Rückgabewert sagt noch mehr aus, je nach dem ob er positiv oder negativ ist, aber das ändert nichts daran dass der Rückgabewert eine große Fehlerquelle ist.
    Für die Entscheidung ob ein String nun kürzer oder länger ist als ein anderer hätte man auch eine andere Funktion dafür einführen können.

    In Java ist der Rückgabetyp von str1.equals(str2) jedenfalls auch in seiner Gesamtheit logisch definiert, denn man kann ihn direkt in einer if Anweisung verwendet ohne ihn noch invertieren zu müssen.



  • Nicht logisch definiert schrieb:

    aber das ändert nichts daran dass der Rückgabewert eine große Fehlerquelle ist.

    Nur für Anfänger. Aber jetzt weißt es ja auch, also wirst den Fehler auch nicht mehr machen.


  • Mod

    Nicht logisch definiert schrieb:

    Für die Entscheidung ob ein String nun kürzer oder länger ist als ein anderer hätte man auch eine andere Funktion dafür einführen können.

    Schön, dass du weiterhin dein tiefgehendes Geheimwissen über die Funktion strcmp zum besten gibst, wenn du darüber meckerst. Da kann sofort jeder sehen, ob du verstehst, wovon du sprichst.

    Aus deiner schnellen Antwort und deinem Nichterwähnen sonstiger Funktionen der Standardbibliothek schließe ich, dass du dich darüber ebensowenig informiert hast, selbst nachdem man dich darauf hingewiesen hat, dass da weitere Gründe zu finden gewesen wären. Tja, man kann einem Schüler, der nicht lernen möchte, nichts beibringen.



  • @OP:

    Wenn du so blöd bist, einen int-Rückgabewert, der -1, 0 und +1 sein kann, implizit als booleschen Ausdruck zu benutzen, statt den Vergleich zwischen Rückgabewert und erwartetem Wert zu testen, bist du selbst schuld.

    if (strcmp(stringA, stringB) == 0)
    // --> stringA == stringB
    
    if (strcmp(stringA, stringB) < 0)
    // --> stringA < stringB
    
    if (strcmp(stringA, stringB) > 0)
    // --> stringA > stringB
    

    Ich finde, es ist sowieso eine stilistische Unart, den Vergleich einer Zahl mit 0 per ! -Operator zu schreiben.

    Am besten noch, wenn es um Characters geht:

    if (!str[i])
    // SCHAUDER!
    // So ist's ordentlich:
    if (str[i] == '\0')
    


  • Nicht logisch definiert schrieb:

    Wer zum Geier denkt sich so einen Mist aus? 😡

    [rant]
    C Programmierer. Leute die sich cool dabei vorkommen sich für schlau zu halten, weil sie Sachen wissen, die man nur wissen muss weil sie Scheisse gemacht sind. Leute die sich darüber streiten ob Vim oder Emacs besser ist und dabei allen ernstes nicht mitbekommen dass beides dreckselendige Drecksdinger sind.
    POSIX, SUS & Co. sind voll mit solchem Ranz.
    [/rant]

    Ja, ist unlogisch*. Man gewöhnt sich dran. Eine Fehlerquelle bleibt es natürlich trotzdem - gerade wenn man es nicht oft verwendet weil man hauptsächlich andere Dinge macht.

    *: Muss mich korrigieren: Es ist schon vollkommen logisch. Es ist nur nicht unbedingt intuitiv, und selbst wenn man es weiss kann man schnell mal auf das == 0 vergessen. Aber unlogisch ist es deswegen nicht.



  • hustbaer schrieb:

    Nicht logisch definiert schrieb:

    Wer zum Geier denkt sich so einen Mist aus? 😡

    [rant]
    C Programmierer. Leute die sich cool dabei vorkommen sich für schlau zu halten, weil sie Sachen wissen, die man nur wissen muss weil sie Scheisse gemacht sind. Leute die sich darüber streiten ob Vim oder Emacs besser ist und dabei allen ernstes nicht mitbekommen dass beides dreckselendige Drecksdinger sind.
    POSIX, SUS & Co. sind voll mit solchem Ranz.
    [/rant]

    Ja, ist unlogisch. Man gewöhnt sich dran. Eine Fehlerquelle bleibt es natürlich trotzdem - gerade wenn man es nicht oft verwendet weil man hauptsächlich andere Dinge macht.

    Danke, endlich jemand der mich versteht.



    strcmp ist eben NICHT eine Gleichheitsprüfung - das ist nur ein Aspekt, wenn die Routine strequal heissen würde wäre ich 100% bei dir

    wenn du bei so einem Fierlefanz schon "Probleme" siehst solltest du noch ein paar Jahre in dem Business arbeiten um zu merken wie absolut keine Relevanz dein Problem in echten Projekten hat

    nur Anfänger schreiben sich keine Hilfsroutinen um "Probleme" zu lösen, es gibt keine Mindestgröße für ein Problem ab der man sich erst eine Hilfsroutine bauen darf
    bool strequal(...){ return strcmp(...) == 0; }

    die Standard-Lib ist im Normalfall dein kleinste Problem in einem Projekt - oder dein Projekt ist eben trivial

    in vielen anderen Sprachen gibt es auch solche "Probleme" die werden aber nie ganz verschwinden - egal ob die Sprache/Libs 70 Jahre oder 1 Jahr als sind - es passiert einfach, die Leute nutzen es und dann musst du eine Strategie haben um damit arbeiten zu können



  • Nicht logisch definiert schrieb:

    In Java ist der Rückgabetyp von str1.equals(str2) jedenfalls auch in seiner Gesamtheit logisch definiert, denn man kann ihn direkt in einer if Anweisung verwendet ohne ihn noch invertieren zu müssen.

    Wenn Du schon mit Java vergleichst, dann nimm auch bitte die korrekte Java-Methode:

    strcmp -> String.compareTo - na, klingelt was?

    Vielleicht sollte man es hier noch etwas verdeutlichen: String.compareTo



  • Gast3 schrieb:

    nur Anfänger schreiben sich keine Hilfsroutinen um "Probleme" zu lösen, es gibt keine Mindestgröße für ein Problem ab der man sich erst eine Hilfsroutine bauen darf
    bool strequal(...){ return strcmp(...) == 0; }

    Als C entstand, wurde das sicher mit einem Makro gelöst:

    #define strequ(s1, s2) (!(strcmp((s1),(s2)))
    

    6. C ist nicht für Anfänger gedacht.


  • Mod

    DirkB schrieb:

    6. C ist nicht für Anfänger gedacht.

    Trotzdem gilt, dass dieser Fall keine Raketenwissenschaft ist. Die Motzer in diesem Thread verwechseln Gleichheit mit einer Ordnungsrelation und sind zu faul (oder eher: nicht interessiert), den Unterschied zu lernen, oder gar mal nachzudenken, wozu man wohl eine Ordnungsrelation für Zeichenketten brauchen könnte. Das Problem liegt eindeutig bei den Motzern selbst. "Ich kapier es nicht, also muss es dämlich sein, denn ich bin schließlich furchtbar klug. Aber ich will auch nicht erklärt bekommen, wieso das so ist".



  • Ich verstehe es und verstand es auch vor deinem schlauen Beitrag. Ich finde es trotzdem Scheisse. Und zwar weniger dass es die strcmp() Funktion gibt und wie deren Returnwert aussieht, sondern mehr dass es eben keine streq() Funktion in der libc gibt. Weil der Effekt davon ist dass jeder strcmp() == 0 schreibt, weil es jedem komisch/unpassend vorkommt sich so eine kleine "unnötige" Hilfsfunktion selbst schreibt. Und der Effekt davon ist wiederrum dass wir haufenweise Code haben der schlechter zu lesen ist als er es sein müsste.

    SeppJ schrieb:

    "Ich kapier es nicht, also muss es dämlich sein, denn ich bin schließlich furchtbar klug. Aber ich will auch nicht erklärt bekommen, wieso das so ist".

    Ich hab überhaupt kein Problem, da ich nicht kaum jemals C programmieren muss. Ein Problem haben die Leute die vor Lauter Müll die Müllhalde nicht sehen und für die grüne grüne Wiese halten.



  • hustbaer schrieb:

    Weil der Effekt davon ist dass jeder strcmp() == 0 schreibt,

    Nö.
    Da wird !strcmp() hingeschrieben.

    Ja, das sieht noch unleserlicher aus und ja, hätte, hätte, hätte.

    Wurde alles nicht gemacht, das war für die Erfinder von C auch nicht wichtig.
    (Das Konzept ist jetzt fast 50 Jahre alt. )

    Und, C ist nicht für Anfänger gedacht.



  • Gast3 schrieb:

    nur Anfänger schreiben sich keine Hilfsroutinen um "Probleme" zu lösen, es gibt keine Mindestgröße für ein Problem ab der man sich erst eine Hilfsroutine bauen darf
    bool strequal(...){ return strcmp(...) == 0; }

    Das ist nicht performant.
    Eher baue ich mir mein eigenes strequal, aber ohne Verwendung von strcmp.



  • DirkB schrieb:

    hustbaer schrieb:

    Weil der Effekt davon ist dass jeder strcmp() == 0 schreibt,

    Nö.
    Da wird !strcmp() hingeschrieben.

    Egal welche Variante genommen wird, beides ist unleserlich, birgt Fehlerquellen und ist auch noch langsam, weil jedes mal eine Negation notwendig ist.

    Würde es strequal in der libc geben, die einen Boolwert zurück liefert, dann gäbe es dieses Problem nicht.

    Mal davon abgesehen, dass ihr euch jetzt widersprecht.
    Du sagst, !strcmp() wäre richtig und BooleanInteger hält es für eine stillistische Unart und empfiehlt deswegen strcmp() == '\0'
    https://www.c-plusplus.net/forum/p2544943#2544943

    Da habt ihr also in der C Community verschiedene Varianten, jeder macht es anders, ein purer Wildwuchs ist da vorprogrammiert und alles nur, weil es kein strequal() in der libc gibt.



  • Halt einfach die Klappe.
    Kommst du dir nicht selbst lächerlich vor, als Laie Erfindern der verbreitetsten Programmiersprache der Welt Dämlichkeit vorzuwerfen?
    C ist von Profis für Profis entwickelt worden - keinesfalls jedoch vor 45 Jahren, damit auch noch nach 45 Jahren der letzte Depp mit beschränktem Horizont und grundsätzlich naiver Vorstellungswelt sofort alles intuitiv begreift.
    Trolle dich zu Java zurück und halte deine Klappe wenn Erwachsene sich unterhalten.



  • Nicht logisch definiert schrieb:

    Du sagst, !strcmp() wäre richtig

    1. Ist das richtig (es funktioniert und ist vom Standard gedeckt)
    2. meinte ich damit, das der weit größte Teil der C-Programmierer das so macht.

    Es werden Kriege um den richtigen Einrücksstil geführt.
    Da ist der Wildwuchs um ein ! oder == 0 doch er ein Scharmützel (gerade bei strcmp)

    Nicht logisch definiert schrieb:

    und BooleanInteger hält es für eine stillistische Unart und empfiehlt deswegen strcmp() == '\0'

    Das tut er garantiert nicht!.
    Es geht um den Stringterminator.
    Darum, dass man ihn hinschreibt. Als Zeichen (nicht als numerischen Wert)



  • Wutz schrieb:

    von Profis für Profis

    Falls du welche kennst könntest du die ja mal fragen was sie davon halten.



  • Nicht logisch definiert schrieb:

    Gast3 schrieb:

    nur Anfänger schreiben sich keine Hilfsroutinen um "Probleme" zu lösen, es gibt keine Mindestgröße für ein Problem ab der man sich erst eine Hilfsroutine bauen darf
    bool strequal(...){ return strcmp(...) == 0; }

    Das ist nicht performant.
    Eher baue ich mir mein eigenes strequal, aber ohne Verwendung von strcmp.

    Keine ahnung was du meinst - als header only implementation ist der overhead zum direkten aufruf exakt 0, wird komplett weg optimiert (schau dir den assemblercode an), war schon vor 30 jahren so


Anmelden zum Antworten