Gegenstück zu atoi/atof



  • It0101 schrieb:

    Der Punkt ist doch, ob es Sinn macht, eine komplette asynchrone SocketLogik auf vector<char> auszulegen, wenn das Interface ( z.b. winsock ) damit gar nichts anfangen kann... Klar wird jetzt einer sagen: "Dann nimm doch boost::asio", aber letztendlich lügt man sich damit selber in die Tasche.

    Wenn man boost-libraries nimmt, die zumindest nach außen ein C++-Interface haben soll das in Ordnung sein, aber wenn man die Socketanbindung selber schreibt mit char * und memXXX ( anders ist das in Boost vermutlich auch nicht gemacht ), dann ist das plötzlich schlechter Stil... Entschuldige bitte, wenn ich das schwachsinnig finde 😉

    Falls sich die Kritik wirklich auf das Vorgehen an sich bezieht, finde ich sie auch ungerechtfertigt, schließlich hat man so einen Performance-Vorteil.
    Was SeppJ aber evtl. eher meinte, war das benutzen der memXXX()-Funktionen anstatt z.B. std::copy(). std::copy() ist halt allgemeiner (funktioniert mit allen Iterator-Typen) ohne Geschwindigkeitsnachteil, von daher sollte man sich das schon angewöhnen... Hier schreibt sogar einer, es sei bei ihm schneller:
    http://stackoverflow.com/questions/4707012/c-memcpy-vs-stdcopy

    Aber wie gesagt, dafür würde ich dich jetzt nicht steinigen wollen.. 😉



  • Ich finde generell, dass viele hier zu dogmatisch unterwegs sind. Erlaubt ist aus meiner Sicht, was in Summe, unter Berücksichtigung aller relevanten Faktoren zum jeweiligen Problem am besten passt.

    Faktoren sind:
    - korrekte Funktion (!!)
    - Wartbarkeit ( da ist C++ meist im Vorteil )
    - Performance ( sofern relevant )
    - Verständlichkeit / Übersichtlichkeit
    - ästhethische Belange ( eher untergeordnet ), ich finde "schönen" Code aber sexy 😉

    Und du sagst ja auch selber, dass du bei std::copy im Vergleich zu memcpy "wenigstens keine Performance-Nachteile" in Kauf nehmen musst. Na herzlichen Dank. 😃

    Aber gut... die C vs. C++-Diskussion ist so alt, wie C++ 😃



  • ... wobei für memcpy() spricht, dass hier sehr viel expliziter dargestellt ist, dass es sich eben um einen Kopiervorgang direkt im Speicher handelt und nicht um einen abstrakten mit den Umwegen über die Iteratoren.



  • It0101 schrieb:

    Und du sagst ja auch selber, dass du bei std::copy im Vergleich zu memcpy "wenigstens keine Performance-Nachteile" in Kauf nehmen musst. Na herzlichen Dank. 😃

    Lies nochmal genauer, von "wenigstens" hab ich nichts gesagt. Im Gegenteil sogar dass es Vorteile hat ohne Nachteile zu haben.

    "- Security" fehlt übrigens noch 😉


  • Mod

    It0101 schrieb:

    Der Punkt ist doch, ob es Sinn macht, eine komplette asynchrone SocketLogik auf vector<char> auszulegen, wenn das Interface ( z.b. winsock ) damit gar nichts anfangen kann... Klar wird jetzt einer sagen: "Dann nimm doch boost::asio", aber letztendlich lügt man sich damit selber in die Tasche.

    Kommt halt drauf an. Woher nimmst du denn den Pufferspeicher? Wenn du jetzt sagst new/malloc, dann wäre das in C++ einfach nur dumm und umständlich, da es eine kürzere, bessere Lösung (vector<char>) gäbe und du einiges an Verrenkungen machen müsstest, um new/malloc von Hand richtig (richtig != halbwegs richtig) zu benutzen.
    Weil ein Interface einen char* verlangt malloc/new zu nehmen, das ist falsch verstanden, was die Bedeutung dieser Datenstruktur ist. Ich vermute aber, das meinst du auch gar nicht, sondern einen festes Array. Da spricht in keiner Sprache etwas gegen und das darfst du auch gerne mit den memXXX-Funktionen behandeln. Das ist ja von der Funktion her gänzlich etwas anderes als vector/new/malloc und dadurch auch nicht ersetzbar. C++-Dogmatiker würden vielleicht ein std::array nehmen. Das kann man sich aber auch sparen, da die ganze Struktur ohnehin in einem struct/class gewrapped sein sollte.



  • Wenn du dein "TicTacToe" codest wird sich keine Sau für Security interessieren. Aber prinzipiell hast du natürlich Recht 😉

    Trotzdem finde ich es sehr aussagekräftig wenn "kein Geschwindigkeitsnachteil" jetzt schon als Vorteil von C++ ins Feld geführt wird 😃



  • @SeppJ:
    Da die Socketfunktionen ( z.b. read ) sowieso einen Buffer (char) wollen, macht ein char-Array an der Stelle Sinn. Ein konstantes normalerweise.

    Man kann aber genauso gut einen char* Buffer mit einer Initialen Laenge anlegen und, wenn man Hinweise hat, dass mehr Daten kommen, den Buffer vergroessern. Hab das zwar so noch nie gemacht, aber es wäre zumindest ein denkbares Szenario.

    Da "read" nur char* nimmt, fällt vector sowieso aus, und wenn man einen flexiblen Buffer haben will, bleibt einem nichts anderes übrig 😉 Das Szenario ist jetzt arg konstruiert, das gebe ich zu, aber es zumindest nicht undenkbar.


  • Mod

    It0101 schrieb:

    Da "read" nur char* nimmt, fällt vector sowieso aus

    Nein. Dann hast du es doch falsch verstanden. vector wäre hier genau das richtige. Geradezu Paradebeispiel für den Denkfehler, den ich mit

    Weil ein Interface einen char* verlangt malloc/new zu nehmen, das ist falsch verstanden, was die Bedeutung dieser Datenstruktur ist.

    meinte.

    Hier wird vom Interface ein Zeiger auf deine Daten verlangt. Das heißt nicht, dass du deine Daten mit einem Zeiger halten musst, sondern dass deine Daten "zeigbar" sein müssen! Sonst würde mit diesem Argument ja nicht einmal das statische char-Array gehen.



  • Ach so meintest du das. Naja ich bin kein Freund davon auf die Art zu arbeiten.

    Wenn gewollt wäre, dass man an die Adresse des internen Arrays von std::vector rankäme, dann wäre das entsprechend mit einer Funktion vorgesehen wie z.b. "c_str" bei std::string.
    Ich betrachte das eher als "Workaround", denn als "schöne" Variante.

    Zumal es bei vector ja tatsächlich gegeben ist, dass die Daten hintereinander im Speicher liegen. Das heißt es wäre geradezu lächerlich einfach, eine Funktion zu bauen, die die Adresse zurückliefert. Das Standardkomitee wird schon seine Gründe haben, warum es eine solche Funktion nicht mitliefert.

    Mich wundert, dass du und andere das wirklich so verwenden, wo ihr doch sonst immer den Standard als die einzige wahre Bibel preist. 😉



  • It0101 schrieb:

    Zumal es bei vector ja tatsächlich gegeben ist, dass die Daten hintereinander im Speicher liegen. Das heißt es wäre geradezu lächerlich einfach, eine Funktion zu bauen, die die Adresse zurückliefert. Das Standardkomitee wird schon seine Gründe haben, warum es eine solche Funktion nicht mitliefert.

    Tut es jetzt wie ich gerade lese: data(). Mich würde auch mal interessieren, ob du das meintest oder was sonst.



  • It0101 schrieb:

    Zumal es bei vector ja tatsächlich gegeben ist, dass die Daten hintereinander im Speicher liegen. Das heißt es wäre geradezu lächerlich einfach, eine Funktion zu bauen, die die Adresse zurückliefert. Das Standardkomitee wird schon seine Gründe haben, warum es eine solche Funktion nicht mitliefert.

    Seit C++11 gibt es sie.
    Aber auch ohne C++11 ist es möglich, da man mit &vector[0] an die Adresse des ersten Arrayelementes kommt (ist vom Standard garantiert).


Anmelden zum Antworten