string.h oder cstring.h

OP #6145251
Lesenswert?

Hallo,

ich hatte mir 2007 von einem (wie ich denke) recht guten Programmierer 
ein Kommandozeilenprogramm für Linux schreiben lassen (ich wollte etwas 
ausführbares, er verwendete damals C++).

Das funktionierte seitdem einwandfrei, die Anwender waren zufrieden, 
einige haben sich das auch mit dem Quelltext für diverse Systeme 
compiliert.

Dieser Tage wollte ich das selbst mit Ubuntu 18.04 compilieren (als Test 
vor der Umsetzung für den Raspi 4).

Dabei kam die Fehlermeldung dass memset nicht spezifiziert sei.
Mit der Änderung von #include <string.h> zu #include <cstring.h> war das 
Problem behoben.

Kurze Frage, da ich dazu nicht viel gefunden habe: gibt es die Funktion 
in der alten Bibliothek nicht mehr?

Und warum hat er damals nicht gleich die neue eingebunden (habe leider 
keinen Kontakt mehr)? Mit anderen Bibliotheken hat er das durchaus 
gemacht, aber die war eben damals noch die alte C-Bibliothek.

Mir geht es nicht um irgendwelche Schuldzuweisungen (wäre nach 13 Jahren 
auch recht abwegig), ich möchte es nur gern verstehen. Bitte erhellt 
mich.
Moderator #6145266
Lesenswert?

Ich kann das Problem nicht reproduzieren. Mit <string.h> und <cstring>
kann memset problemlos verwendet werden, nur mit <cstring.h> gibt es
eine Fehlermeldung, da dieser Header nicht existiert.

Wie genau lautet die Fehlermeldung?

Kannst du ein einfaches Code-Beispiel posten, in dem der Fehler
auftritt?
OP #6145278
Lesenswert?

Ja, da war ich ungenau.

Das stand im Quelltext von 2007:

#include <cstdio>
#include <cstdlib>
#include <string>

Ich bin jetzt auch nicht sicher ob ich das damals selbst compiliert 
habe, die ausführbare Datei die er übergab funktionierte ja.

Auf jeden Fall musste ich es jetzt auf #include <cstring> ändern und die 
Fehlermeldung vom Compiler war weg.

Meint ihr das hat schon damals nicht funktioniert?
Gast #6145319
Lesenswert?

Korrekt ist <cstring> und std::memset .
Einfach nur memset ohne std:: kann gehen, muss aber nicht (erlaubte 
optionale Abwärtskompatibilität). Durch ein "using std::string;" am 
Anfang der Datei kann man sicher gehen, dass auch nur "memset" geht. 
Dito für die anderen C-Funktionen und auch C-Typen wie size_t (korrekt: 
std::size_t) in C++.
<string.h> statt <cstring> kann gehen, muss aber nicht  (erlaubte 
optionale Abwärtskompatibilität).
<cstring.h> existiert nicht.
Gast #6145717
Lesenswert?

Wilhelm M. schrieb:
> Schwerwiegender ist die mangelnde exception-safety und dadurch
> deadlock-unsafety.

Stimmt. Wobei die nicht trivial zu erreichen ist. Der Code ruft 
Konstruktoren und Destruktoren auf, während er ein Mutex hält. Wenn 
diese wiederum andere Mutexe locken, und ein anderer Thread dann 
gleichzeitig drauf zugreifen will...
#6145720
Lesenswert?

Programmierer schrieb:
> Wilhelm M. schrieb:
>> Schwerwiegender ist die mangelnde exception-safety und dadurch
>> deadlock-unsafety.
>
> Stimmt. Wobei die nicht trivial zu erreichen ist. Der Code ruft
> Konstruktoren und Destruktoren auf, während er ein Mutex hält. Wenn
> diese wiederum andere Mutexe locken, und ein anderer Thread dann
> gleichzeitig drauf zugreifen will...

Zumindest sollte man Mal RAII (Scoped Locker) einsetzen.
Gast #6145884
Lesenswert?

Das sowieso. Man könnte auch den self-pipe-Trick mit select verwenden um 
das ständige Aufwachen zu vermeiden und das Beenden zu beschleunigen. 
Eigentlich braucht man auch überhaupt keinen zusätzlichen Thread, und 
könnte die accept-Loop auch in die Event-Loop vom Main Thread 
integrieren, falls vorhanden.
OP #6146871
Lesenswert?

Vielen Dank für die Anregungen in Richtung besserem, modernerem C++.

Ich kann sie leider mangels so tiefer Kenntnisse in der Sparte nicht 
umsetzen, für dieses kleine Programmchen (das seit Jahren klaglos seinen 
Dienst tut) ist das aber im Moment auch nicht erforderlich.

Habe mir aber auf jeden Fall mal Boost auf dem Raspi installiert und 
einige der Beispiele compiliert.
Moderator #6146940
Lesenswert?

Hier ist noch eine mögliche Ursache dafür, dass die Software früher
fehlerfrei kompiliert werden konnte, heute aber nicht mehr:

Kann es sein, dass das Programm eine externe Bibliothek benutzt? Wenn in
deren Header-File direkt oder indirekt <string.h> inkludiert wird, ist
memset überall dort bekannt, wo das Header-File benutzt wird.

Durch ein Update dieser Bibliothek könnte das #include <string.h> im
Header-File weggefallen sein, so dass nun auch memset nicht mehr bekannt
ist.

Man sollte sich natürlich nicht auf solche eher zufällig stattfindenden
Includes verlassen, sondern selber dafür Sorge tragen. Im konkreten Fall
geschieht dies dadurch, dass man <cstring> in connectionmanager.cpp
inkludiert, was du ja inzwischen auch gemacht hast.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren