Forum: PC-Programmierung string.h oder cstring.h


von Lutz S. (lutzs)


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.

von Yalu X. (yalu) (Moderator)


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?

von Dirk B. (dirkb2)


Lesenswert?

meinst du <cstring> ohne .h

Das ist halt C++ Standard.

Evtl liegt es am benutzten C++ Standard.

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

Lutz S. schrieb:
> Dabei kam die Fehlermeldung dass memset nicht spezifiziert sei.

memset() ist immer in <string.h> definiert.

Der Fehler liegt woanders. Außerdem gibt es <cstring.h> nicht.

von Lutz S. (lutzs)


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?

: Bearbeitet durch User
von Dirk B. (dirkb2)


Lesenswert?

mag sein, dass memset noch in <cstdlib> deklariert war

von Oliver S. (oliverso)


Lesenswert?

https://en.cppreference.com/w/cpp/header/cstring

<string> ist ein ganz anderer Header, der hat mit string.h/cstring 
nichts zu tun.

Oliver

von Programmierer (Gast)


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.

von Wilhelm M. (wimalopaan)


Lesenswert?

Lutz S. schrieb:
> #include <string>

Schau doch mal nach, ob es in Den Sourcen zu diesem Programm eine 
Dateien mit dem namen "string" (ohne Suffix) gibt?

von Lutz S. (lutzs)


Angehängte Dateien:

Lesenswert?

Nein, Datei "string" gibt es in den Sourcen nicht.

Ich hänge mal das Original an, in Zeile 69 kam es dann zum Fehler beim 
compilieren.

von Programmierer (Gast)


Lesenswert?

Es fehlt eindeutig <cstring> . Der Code ist etwas altmodisch und könnte 
an C++17 angepasst und verschönert werden, insb. unter Nutzung von 
std::unique_ptr und der C++ Thread Klassen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Programmierer schrieb:
> Der Code ist etwas altmodisch und könnte
> an C++17 angepasst und verschönert werden, insb. unter Nutzung von
> std::unique_ptr und der C++ Thread Klassen.

Schwerwiegender ist die mangelnde exception-safety und dadurch 
deadlock-unsafety.

von Programmierer (Gast)


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

von Wilhelm M. (wimalopaan)


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.

von Lutz S. (lutzs)


Lesenswert?

Ich muss gestehen dass ich euch hier nicht mehr folgen kann, aber 
zumindest habe ich die Begriffe mal nachgeschlagen um etwa zu wissen 
wovon ihr schreibt.

von Programmierer (Gast)


Angehängte Dateien:

Lesenswert?

Im Anhang eine erste Annäherung zu einer möglichen Modernisierung des 
Codes...

von cppbert (Gast)


Lesenswert?

das auf Asio (auch ohne Boost) zu portieren wuerde den Code noch mal 
ordentlichst eindampfen

von Programmierer (Gast)


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.

von Lutz S. (lutzs)


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.

von Yalu X. (yalu) (Moderator)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.