Forum: Projekte & Code C-Werkstatt für Linux Projekte


von Günther S. (projekt_c)


Lesenswert?

Bei meiner Beschäftigung mit dem Raspberry Pi ist eine umfangreiche 
C-Werkstatt entstanden.

Ich würde gerne im Sinne des Open Source Gedankens etwas zurückgeben und 
suche einen
Autor für ein Buch oder einen Blog rund um das Thema 'Praktischer 
Einsatz von C'.

Das Ergebnis können Sie unter http://www.schmuckhexen.at [Projekt /c] 
einsehen.
Vorwort http://www.schmuckhexen.at/programs/c/clar_vorwort.pdf.
Kapitel: 'Projekt c/' und 'Autoren gesucht'

Vielleicht können Sie mir weiterhelfen. Danke

Günther Schardinger, Austria, Trofaiach
Webseite : http://www.schmuckhexen.at/
Websuche : schardinger linux c
eMail : v.schardinger@gmx.net

von Sherlock 🕵🏽‍♂️ (Gast)


Lesenswert?

Günther S. schrieb:
> Ich würde gerne im Sinne des Open Source Gedankens etwas zurückgeben und
> suche einen
> Autor für ein Buch

Verstehe ich nicht. Wenn du etwas zurück geben willst, dann bist DU der 
Autor.

von Axel S. (a-za-z0-9)


Lesenswert?

Günther S. schrieb:
> Bei meiner Beschäftigung mit dem Raspberry Pi ist eine umfangreiche
> C-Werkstatt entstanden.

Hmm. Was ist eine C-Werkstatt? Und Linux gibt es seit über 30 Jahren, C 
noch länger. Da gibt es schon gefühlt 1000 Tutorials. Der RasPi ist halt 
nur eine (weitere) Plattform auf der Linux läuft.

Versteh mich nicht falsch. Ich will das nicht madig machen. Es sieht 
nach viel Arbeit aus. Und einige der o.a. Tutorials sind schlechter als 
deins. Trotzdem stellt sich halt die Frage nach dem Sinn. Hoffentlich 
hattest du wenigstens Spaß dabei.

> Ich würde gerne im Sinne des Open Source Gedankens etwas zurückgeben und
> suche einen
> Autor für ein Buch oder einen Blog rund um das Thema 'Praktischer
> Einsatz von C'.
>
> Das Ergebnis können Sie unter http://www.schmuckhexen.at [Projekt /c]
> einsehen.

Sieht doch gut aus. Wozu brauchst du da noch einen (weiteren) Autor? 
Wird es dir zuviel? Dann hör auf.

von Günther S. (projekt_c)


Lesenswert?

Danke für Beiträge.
Ein paar Antworten:
1. Die Werkstatt Projekt /c erleichtert das Programmieren mit C.
2. Wiso und Warum unter: 
https://www.projektc.at/programs/c/clar_vorwort.pdf
3. Das Ausprobieren der Werkstatt ist sehr einfach: 
https://www.projektc.at/programs/c/clar_start.pdf
4. Die Sprache C ist zwar sehr einfach. Die Projektorganisation nicht.
5. Projekt /c bietet umfangreiche Lösungen zu den Defiziten von C.

Neues Beispiel: Programm 'wwwtool' zum Bearbeiten/Warten von Webseiten.

Siehe: https://www.projektc.at/programs/c_bsp/wwwtool/index.html

Servus, Günther

von Ein T. (ein_typ)


Lesenswert?

Günther S. schrieb:
> Danke für Beiträge.

Es wäre vermutlich sinnvoll, Deinen früheren Thread zu verlinken.

von Cyblord -. (cyblord)


Lesenswert?

Die ganze Seite gibt mir nostalgische Gefühle.

Was soll der Unsinn?

Günther S. schrieb:
> Neues Beispiel: Programm 'wwwtool' zum Bearbeiten/Warten von Webseiten.

So erstellt und wartet niemand seit 1995 mehr Webseiten.

Ehrliche Frage: Was denkst du in welchem Jahr wir uns aktuell befinden? 
Wann bist du hängengeblieben?

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Ein T. schrieb:
> Es wäre vermutlich sinnvoll, Deinen früheren Thread zu verlinken.

Ich habe beide Threads (den alten und den neuen) zusammengeführt.

An Günther S. (projekt_c): Bitte nicht jedesmal einen neuen Thread 
öffnen, sondern den bereits vorhandenen Thread nutzen, solange es kein 
neues Thema ist.

: Bearbeitet durch Moderator
von Cyblord -. (cyblord)


Lesenswert?

Frank M. schrieb:
> An Günther S. (projekt_c): Bitte nicht jedesmal einen neuen Thread
> öffnen, sondern den bereits vorhandenen Thread nutzen, solange es kein
> neues Thema ist.

Der Günther macht eh immer nur Fire and Forget und geht auf nichts ein. 
Im Grunde spamt er nur Werbung für seine Seite.

: Bearbeitet durch User
von Klaus (feelfree)


Lesenswert?

Ist doch wunderbar das Projekt!

Wo kann man sonst schon 30 Jahre in die Vergangenheit reisen, ganz ohne 
Wayback-Machine und Flux-Kompensator.

von Günther S. (projekt_c)


Lesenswert?

Ich habe die Erklärungen zu Projekt /c durch
Grundlegende Konzepte und weiter Beispiele erweitert.

Webseite : https://www.projektc.at

von Alexander S. (alesi)


Lesenswert?

Günther S. schrieb:
> Ich habe die Erklärungen zu Projekt /c durch
> Grundlegende Konzepte und weiter Beispiele erweitert.
>
> Webseite : https://www.projektc.at

Du schreibst:
"Die geprüften Bibliotheken beheben Defizite der Linuxbibliothek 'Libc'.
Beispiel: Libc Funktion strcmp(NULL,NULL) stürzt ab, die Funktionkopie 
StrCmp(NULL,NULL) nicht."
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
int
6
main(void)
7
{
8
9
    printf("res = %d\n", strcmp(NULL, NULL));
10
11
    return EXIT_SUCCESS;
12
}

[bash]
~/C/test$ gcc -Wall -pedantic -std=c99 -o tstrcmp tstrcmp.c
tstrcmp.c: In function ‘main’:
tstrcmp.c:9:26: warning: argument 1 null where non-null expected 
[-Wnonnull]
    9 |     printf("res = %d\n", strcmp(NULL, NULL));
      |                          ^~~~~~
In file included from tstrcmp.c:3:
/usr/include/string.h:156:12: note: in a call to function ‘strcmp’ 
declared ‘nonnull’
  156 | extern int strcmp (const char *__s1, const char *__s2)
      |            ^~~~~~
tstrcmp.c:9:26: warning: argument 2 null where non-null expected 
[-Wnonnull]
    9 |     printf("res = %d\n", strcmp(NULL, NULL));
      |                          ^~~~~~
/usr/include/string.h:156:12: note: in a call to function ‘strcmp’ 
declared ‘nonnull’
  156 | extern int strcmp (const char *__s1, const char *__s2)
      |            ^~~~~~
~/C/test$ ./tstrcmp
res = 0
~/C/test$ echo $?
0
[/bash]

Bei mir unter Debian/GNU-Linux mit gcc stürzt es nicht ab. gcc warnt vor 
der Verwendung der NULL-Pointer und strcmp liefert 0 zurück, da beide 
pointer gleich sind.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Alexander S. schrieb:
> "Die geprüften Bibliotheken beheben Defizite der Linuxbibliothek 'Libc'.
> Beispiel: Libc Funktion strcmp(NULL,NULL) stürzt ab, die Funktionkopie
> StrCmp(NULL,NULL) nicht."

Dem C-Standard zufolge ist das Übergeben von NULL-Pointern an strcmp 
"undefined behaviour", es darf also irgendwas passieren (Rückgabe 42, 
Programmabsturz, Festplatte formatiert). Es handelt sich also nicht um 
einen Fehler. Dass die gnu libc bei solch elementaren Funktionen 
fehlerhaft wäre, wäre auch sehr schwer vorstellbar...

von Günther S. (projekt_c)


Lesenswert?

Lieber Alexander!
Danke für Deine Antwort!

Ich habe nicht vor an C-Standard zu rütteln. Im Gegenteil: Dieser
Standard hat es mir erst ermöglicht, Projekt /c zu implementieren.
Basis ist nur Linux, gcc und Libc.

Für mich geht es um die Möglichkeit umfangreiche Projekte zu realisieren
und nicht um eine Programmiersprache.

Beispiel: Schon das Hifsprogramm 'chelp' hat derzeit bereits 4791 Zeilen
Programmcode. Da möchte ich nicht ständig auf NULL prüfen müssen.
Meine Lösung: Zu strcmp(...) gibt es die geduldige Funktion StrCmp(..)

Die Bibliotheksfunktionen von Projet /c bieten sichere und komplexe 
Systemaufrufe. Sie können aber müssen nicht verwendet werden!

Vielleicht magst Du https://www.projektc.at einmal ausprobieren.
Es lässt sich rückstandsfrei entfernen.

Servus, Günther

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Günther S. schrieb:
> Da möchte ich nicht ständig auf NULL prüfen müssen

So ist das aber halt wenn man in C programmiert - man macht alles von 
Hand, auch Fehlerbehandlung. In anderen Sprachen wie C++, Rust, Java, 
Python, Kotlin ... geht das viel einfacher.

von Alexander S. (alesi)


Lesenswert?

Günther S. schrieb:
> Beispiel: Schon das Hifsprogramm 'chelp' hat derzeit bereits 4791 Zeilen
> Programmcode. Da möchte ich nicht ständig auf NULL prüfen müssen.
> Meine Lösung: Zu strcmp(...) gibt es die geduldige Funktion StrCmp(..)

Hallo Günther,
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
/* Aus ProjektC/c/lib/include/utils.h */
6
int   StrCmp(const char*a, const char *b);   // wie strcmp(), case-sensitiv
7
8
int
9
main(void)
10
{
11
12
    printf("res = %d\n", StrCmp(NULL, NULL));
13
14
    return EXIT_SUCCESS;
15
16
}
17
18
/* Aus ProjektC/c/lib/utils/utils.c */
19
int StrCmp(const char*a, const char *b)
20
{ if (!a && !b) return 0;
21
  if (a  && !b) return 1;
22
  if (!a &&  b) return -1;
23
  return strcmp(a,b);
24
} // --------------------------------------
1
~/C/test$ gcc -Wall -pedantic -std=c99 -o pstrcmp pstrcmp.c 
2
~/C/test$ ./pstrcmp 
3
res = 0
4
~/C/test$ echo $?
5
0

Zum Vergleich
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
int
6
main(void)
7
{
8
9
    printf("res = %d\n", strcmp(NULL, NULL));
10
11
    return EXIT_SUCCESS;
12
13
}
1
~/C/test$ gcc -Wall -pedantic -std=c99 -o tstrcmp tstrcmp.c 
2
tstrcmp.c: In function ‘main’:
3
tstrcmp.c:9:26: warning: argument 1 null where non-null expected [-Wnonnull]
4
    9 |     printf("res = %d\n", strcmp(NULL, NULL));
5
      |                          ^~~~~~
6
In file included from tstrcmp.c:3:
7
/usr/include/string.h:156:12: note: in a call to function ‘strcmp’ declared ‘nonnull’
8
  156 | extern int strcmp (const char *__s1, const char *__s2)
9
      |            ^~~~~~
10
tstrcmp.c:9:26: warning: argument 2 null where non-null expected [-Wnonnull]
11
    9 |     printf("res = %d\n", strcmp(NULL, NULL));
12
      |                          ^~~~~~
13
/usr/include/string.h:156:12: note: in a call to function ‘strcmp’ declared ‘nonnull’
14
  156 | extern int strcmp (const char *__s1, const char *__s2)
15
      |            ^~~~~~
16
~/C/test$ ./tstrcmp 
17
res = 0
18
~/C/test$ echo $?
19
0

D.h. StrCmp lässt sich mit NULL Pointern aufrufen ohne beim Compilieren 
eine Warnung zu erzeugen. Soll das der Vorteil ggü. strcmp der stdlib 
sein?
Kannst Du genau beschreiben was der Vorteil von StrCmp ggü. strcmp der 
stdlib sein soll? Kannst Du genau beschreiben welche Defizite in "Die 
geprüften Bibliotheken beheben Defizite der Linuxbibliothek 'Libc'" 
gemeint sind. Was genau meinst Du mit "Zu strcmp(...) gibt es die 
geduldige Funktion StrCmp(..)". Meinst Du mit "geduldig" "unterdrückt 
Warnungen beim Compilieren und erlaubt die Verwendung von NULL 
Pointern"?

: Bearbeitet durch User
von Günther S. (projekt_c)


Lesenswert?

Erstmal vielen Dank für diese konstruktive Diskusion!
1
 void Test()
2
{ clrScr();
3
  printf("Laufzeit Test\n");  
4
  char *s=NULL;
5
  char *t=NULL;
6
  printf("s=%s t=%s\n", StrN(s),StrN(t));
7
  printf("strcmp(s,s) ->%i\n", strcmp(s,t));
8
    
9
  WeiterMitTaste();
10
}
1
Laufzeit Test
2
s=NULL t=NULL
3
Speicherzugriffsfehler (Speicherabzug geschrieben)

Test mit gnuc 13.3.0 und Libc 2.39. Den Startwert für uninitialisierte 
Pointer und Objektpointer setze ich immer erstmals auf NULL.

Ich wollte mir keine unnötige Arbeit aufhalsen. Als Einzellkämpfer macht
Programmieren aber nur Spaß, wenn die eigenen Programme wirklich 
funktionieren.

Trotz sorgfältiger Codierung wird es Fehler geben. Fehlermeldungen
wie "Speicherzugriffsfehler (Speicherabzug geschrieben)" sehr sind 
mühsam.

Meine Fehlermeldungen ermöglichen es sofort mit 'Text suchen' die Stelle 
im Sourcecode zu finden. Dazu kann man auch das einfache aber 
reichaltige Fehlerobjekt Err benutzen.

Nochmals: Projekt /c zwingt zu nichts. Wer möchte kann gerne strcmp(...) 
benutzen.

Weitere Fragen beantworte ich gerne!

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Also mich erinnern solche Projekte wie hier eher an sowas: Beim 
Einschlagen von Naegeln, einfach die Hand, die die Naegel haelt, lokal 
betaeuben. Dann tut's auch nicht weh, wenn man mal daneben kloppt...

Ich bevorzuge einfach mal die Warnings des gcc zu aktivieren und nicht 
zu ignorieren und ihrer Ursache auf den Grund gehen. Und die auch auf 
Englisch belassen, dann findet man deutlich mehr dazu im Netz.
Dann nochmal ein Lauf mit valgrind und dort eigenartigen Meldungen 
nachspueren und der Drops ist deutlich nachhaltiger gelutscht, als mit 
irgendwelchen windigen glibc-Funktionsverschlimmbesserungen.

Gruss
WK

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Günther S. schrieb:
> Trotz sorgfältiger Codierung wird es Fehler geben. Fehlermeldungen
> wie "Speicherzugriffsfehler (Spe

Findest du? Wenn du das Programm im Debugger (gdb) startest findest du 
solche Fehler (NULL-Pointer-Zugriff) sofort.

von Günther S. (projekt_c)


Lesenswert?

Der Debugger hilft erst, wenn der Fehler aufgetreten ist!

Ich habe im Projekt /c 317 Stellen mit Str-Tests gefunden.
Es geht um das Laufzeitverhalten. Ich sehe als Mathematiker keine 
Möglichkeit mit Test herauszufinden, unter welchen Bedingungen diese 
Test schief laufen könnten.

Die einfachste Lösung: Alle Tests funktionieren immer. Str NULL ist ja 
kein Fehler!

Jeder Programmierer kann da seine eigene Lösung finden!
Wenn es um funktionierende Programme geht bringen solche
Diskusionen nicht weiter.

von Cyblord -. (cyblord)


Lesenswert?

Günther S. schrieb:
> Der Debugger hilft erst, wenn der Fehler aufgetreten ist!

Wenn Debugging der Vorgang ist, Fehler aus dem Code auszubauen, ist 
Programmierung der Vorgang die Fehler einzubauen.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Günther S. schrieb:
> Ich sehe als Mathematiker keine
> Möglichkeit mit Test herauszufinden, unter welchen Bedingungen diese
> Test schief laufen könnten.

Richtig, das geht grundsätzlich nicht (verwandt mit Halteproblem, Satz 
von Rice).

Günther S. schrieb:
> Die einfachste Lösung: Alle Tests funktionieren immer. Str NULL ist ja
> kein Fehler!

Heißt aber auch, dass du zuvor auftretende Fehler verschleierst - wenn 
irgendein String eigentlich nie NULL sein sollte, aber doch mal NULL 
wird, wird dein StrCmp das einfach ignorieren und du wunderst dich 
warum. Wenn das strcmp aber abstürzt, findest du schnell den Fehler. 
Wichtiges Konzept: Fehler möglichst früh finden (auch durch Absturz), 
statt später zu ignorieren. Abstürze können etwas Gutes sein, um Fehler 
zu finden. Die kann man daher auch gezielt per assert() herbeiführen.

Ich würde grundsätzlich versuchen, String-Pointer nie NULL werden zu 
lassen. Wenn eine Funktion (z.B. strdup()) doch mal NULL zurückgibt, 
sollte man lieber direkt abbrechen/Programm beenden (z.B. per abort()). 
Wenn man den NULL-Pointer hier aber "erlaubt" und dann später in einem 
eigenen StrCmp() ignoriert, hat man erfolgreich den ursprünglichen 
Fehler verschleiert und findet ihn nicht mehr so leicht, hat aber 
wahrscheinlich nichts gewonnen, weil der gewünschte String nicht 
existiert und das Programm nichts sinnvolles mehr machen kann. Ein 
Programm, das kein sinnvolles Ergebnis mehr abliefern kann, kann man 
auch abstürzen lassen.

Natürlich gibt es auch Situationen wo ein String (oder sonst irgendein 
Pointer) durchaus mal NULL sein darf. Dann muss man aber überall dort, 
wo man den Pointer nutzt, eine Überprüfung auf NULL einbauen. Und das 
gehört eigentlich nicht in Low-Level-Funktionen wie strcmp, sondern in 
das Modul/Funktion, die den Pointer deklariert. Modernere Sprachen haben 
Optional- oder Nullable-Typen, mit denen sich explizit Werte/Referenzen 
deklarieren lassen, die leer sein können - hier muss man immer 
explizit auf Null prüfen, sonst gibt's Compiler-Fehler. Stringvergleiche 
akzeptieren dort keine Optional-Typen, d.h. die Prüfung auf "leer" 
obliegt dem Aufrufer.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Günther S. schrieb:
> Ich habe im Projekt /c 317 Stellen mit Str-Tests gefunden.

Und wer hat diese 317 Stellen programmiert?
(Und ich bin auf 10 Planeten zum Tode verurteilt. :-))
Komischerweise hab' ich mir mit C schon ein paarmal in den Fuss 
geschossen und mir sind Daemonen aus der Nase gekommen. Aber noch nie 
mit strcmp() mit NULL-ptr Aufrufen.

Günther S. schrieb:
> Str NULL ist ja
> kein Fehler!

Es ist halt ein Fehler, irgendwelche Funktionen mit NULL ptr aufzurufen, 
die dafuer nicht gemacht sind. Ich traue den libc Schreibern und 
Standardisierern mehr als dir. Bei free() ist ja was eingebaut, dass man 
das mit NULL aufrufen kann und alles ist prima. Die werden schon Gruende 
haben, sowas nicht ueberall einzubauen.

Gruss
WK

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Dergute W. schrieb:
> Es ist halt ein Fehler, irgendwelche Funktionen mit NULL ptr aufzurufen,
> die dafuer nicht gemacht sind.

So ist es.

Günther S. schrieb:
> Ich sehe als Mathematiker

Als Mathematiker&Informatiker kann ich sagen:

Die ideale Lösung ist es eine Sprache zu nutzen die 
Nullable/Optional-Typen kennt und strikt prüft wie Rust oder Kotlin; C++ 
unterstützt das nur so halb mit std::optional, aber Pointer sind 
weiterhin ungeprüft. Durch diese statische Prüfung umgeht man das 
Unentscheidbarkeitsproblem, indem man sich vom Compiler dazu zwingen 
lässt, einfach den Problemraum zu reduzieren.

Wenn es C sein muss gibt es keine strikte Compiler-Prüfung, aber man 
kann das Verhalten manuell nachmachen, indem man wie erwähnt zwischen 
Pointern unterscheidet die NULL sein dürfen und solche bei denen es 
"verboten" ist, und für zweitere eben vor dem Zuweisen auf NULL prüft 
und ggf. terminiert.

So verhindert man das unerwartete NULL-Werte zu späteren Fehlern führen 
und implementiert eine sinnvolle Fehlerbehandlung; vergisst man die 
Prüfung irgendwo, verhindert das Weglassen der NULL-Prüfung vor 
strcmp() etc. das Verschleiern von Fehlern und erleichtert die Suche 
nach dem zuvor gemachten Fehler.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Günther S. schrieb:
> Die einfachste Lösung: Alle Tests funktionieren immer. Str NULL ist ja
> kein Fehler!

Mir wäre dabei unwohl, meine Programmierfehler durch eine "tolerante" 
Funktion zu kaschieren. Wenn sie nicht mehr zu Tage treten, wie soll ich 
sie dann beheben?

Deine Lösung erschwert für mich die Fehlersuche. Natürlich kann ein gcc 
mich nicht davor warnen, wenn ich einen NULL-Pointer übergebe, der erst 
zur Laufzeit gesetzt wird. Dann bin ich aber froh, wenn das Programm zur 
Laufzeit crasht. Mit einem core dump bzw. durch einen Debugger findet 
man dann schnell die entsprechende Stelle und den Verursacher.

Dann gibt es zwei Möglichkeiten:

1. Der Null-Pointer ist harmlos. Dann rufe ich meine Funktion, die einen 
gesetzten Pointer != NULL erwartet, nur bedingt auf. Durch diese 
Codierung teile ich dem geneigten Leser mit: "Achtung, NULL Pointer kann 
durchaus vorkommen und ist getrennt zu betrachten!". Das kann zum 
Beispiel ein simples
1
  if (ptr != NULL)
2
  {
3
    int i = strcmp (ptr, "foo");
4
    ...
5
  }
sein.

2. Der Null-Pointer ist fatal und tritt wegen einer Ausnahmesituation 
auf, z.B. durch einen vorherigen Bug im Programm. Dann ist es nicht 
sinnvoll, das Programm weiterlaufen zu lassen, weil die Gefahr eines 
Amoklaufes besteht, der weitere unvorhersehbare Konsequenzen haben kann.

Mit Deiner Funktion StrCmp() verwässerst Du die beschriebene Situation 
Nr. 2 und gefährdest unter Umständen die Sicherheit Deines Systems zur 
Laufzeit.

Mein Fazit:

Laufzeitfehler zu ignorieren kann fatale Auswirkungen haben. Es gibt 
gute Gründe, warum die libc so ist wie sie ist.

P.S.

Natürlich: die Anwendung der libc ist nicht immer komfortabel und 
zeitweise wirkt sie recht angestaubt, was der Enwicklung seit 1970 
geschuldet ist. Aber deshalb macht diese Tatsache Deine StrCmp-Funktion 
nicht zu einer besseren Funktion - ganz im Gegenteil.

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.