Wozu C Programmieren?

andy_m4 schrieb:
Naja. Das ist ja nicht das Einzige was Funktionale Sprachen ausmachen (wobei Racket ja eine Multiparadigmen-Sprache ist).
Wie C++

andy_m4 schrieb:
Zum Beispiel das Vorzugsverweise mit unveränderlichen "Variablen" (quasi Konstanten; immutable) gearbeitet wird. Das man versucht einen Status und Seiteneffekte zu vermeiden.
Absolut kein Problem mit C++, bzw. nicht mehr ein Problem in C++ als andere Dinge 😁

andy_m4 schrieb:
Außerdem löst man Sachen bevorzugt mit Rekursion. Das bedingt aber auch, das man Tail-Call-Optimization hat, damit man nicht so schnell Stacküberläufe bekommt.
Auch das fehlt Java und C++.
Braucht man nicht, da man ja nicht gezwungen ist das Problem rekursiv zu lösen.

Ansonsten dürfte das eine Compilersache und keine C++ Sache sein - was anscheinend bei den Mainstream C++compiler kein Problem darstellt: Which, if any, C++ compilers do tail-recursion optimization? - Stack Overflow
 
KitKat::new() schrieb:
Ja. Ist es. Aber es hat schon eine bevorzugte Art sich programmieren zu lassen.
Bei Racket ist das etwas anders. Das ist zwar auch eine Sprache die man vermutlich eher dem funktionalem Paradigma zuordnen würde aber im Grunde ist das eher ein Sprachbaukasten. Eigentlich ganz in Lisp-Tradition. Nur das Racket das auf die Spitze treibt. :-)
Die Sprachen müssen dann nicht mal aussehen wie ein typisches Lisp oder Scheme.

KitKat::new() schrieb:
Absolut kein Problem mit C++, bzw. nicht mehr
Generell kannst Du sowieso in jeder Sprache alles machen. Du kannst Dir in C++ auch nen Garbage Collector bauen und für Deine C++ Programme benutzen. Trotzdem würde niemand auf die Idee kommen C++ als GC-Sprache zu sehen.

Worum es mir ging ist, wozu einem die Sprache quasi ermuntert zu benutzen. Welche Vorgehensweise also idiomatisch ist. Und dementsprechend sehen dann auch die Programme völlig unterschiedlich aus.
Ich hatte ja bereits das Beispiel mit der Rekursion genannt. Rekursive Lösungen findet man in einer funktionalen Sprache häufiger als z.B. in Java oder in C++.
Gleiches gilt dann auch für Konstanten.

KitKat::new() schrieb:
ein Problem in C++ als andere Dinge 😁
Absolut.
Wie gesagt. Es ging auch nicht um "Problem". Sondern um das befördern von typischen Lösungen.

KitKat::new() schrieb:
Braucht man nicht, da man ja nicht gezwungen ist das Problem rekursiv zu lösen.
Nein ist man nicht. Es war nur ein Beispiel dafür, wie Spracheigenschaften dazu führen, das man unterschiedliche Lösungsansätze bevorzugt anwendet.

KitKat::new() schrieb:
Ansonsten dürfte das eine Compilersache und keine C++ Sache sein
Ja. Ist definitiv eine Compilersache. Aber viele Compiler außerhalb von funktionalen Sprachen haben das halt nicht. Brauchen es aber auch nicht, weil dort eh Rekursion nicht im größeren Umfang eingesetzt wird.
 
Mathwork schrieb:
Kann ich auch auf meinem MacBook mit C programmieren (wenn ja, wie?)
Natürlich geht das. Vorher die xcode cli tools installieren und dann geht's los.
vim foo.c
cc -o foo foo.c
./foo

man 3 foo für die jeweiligen funktionen der libc. Freu dich, dass du mit C beginnen kannst/darfst. Setze dich viel mit der strukturierten Programmierung auseinander und lerne die Vorzüge von Pointern kennen. C ist nach wie vor die Sprache des Internets, auch wenn hier vieles mittlerweile abgelöst wird.
Linux Kernel - Powered by C
GNU Userland - mostly powered by C
nginx - powered by C
apache - powered by C
php - mostly powered by C
redis - powered by C
postgresql - powered by C
python - powered by C

Ansonsten sind viele kleine aber feine tools wie ffmpeg, lame in C geschrieben und Doom/Quake1-3 darf man natürlich auch nicht vergessen ;)

Ergänzung ()

Oma Erna schrieb:
C kann inzwischen Pointer?
Und da bist du dir sicher?
LOL, ist das dein ernst? int* foo;
Pointer machen C aus.
Ergänzung ()

peter.hahn schrieb:
und alles was du in C machen kannst, kannst du auch mit C++ machen..
Nein, kann man nicht. Und vieles auch nur sehr umständlich/langsamer.
 
Zuletzt bearbeitet von einem Moderator:
foo_1337 schrieb:
und lerne die Vorzüge von Pointern kennen
Wobei Pointer (gerade in dieser Raw-Form wie bei C) nicht ganz ohne sind. Also insbesondere Pointer-Arithmetik und solche Spielereien.
Was wir dem Kram schon an BufferOverflows , SEGFAULTs usw. zu verdanken haben, weil jemand nicht aufgepasst hat, das geht auf keine Kuhhaut. Und das mit dem "nicht aufpassen" geht schneller als man denkt. :-)

Aber ja. Sonst stimme ich Dir zu. C-like Pointer haben durchaus einen gewissen Fun-Factor.

foo_1337 schrieb:
Und vieles auch nur sehr umständlich/langsamer.
Das kann man so nicht unbedingt sagen. Gerade die Geschwindigkeitssache stimmt so überhaupt nicht mehr. Das war früher noch anders wo es keine ausgereiften C++-Compiler gab. Da hat man ja C++ erst mal nach C compiliert und dieses Ergebnis dann erst durch nen C-Compiler gejagt und solche Geschichten.
Aber all dies ist jetzt schon 30 Jahre her.

Was aber geblieben ist, ist ein Geschwindigkeitsunterschied zwischen nem C Compiler und nem C++ Compiler.
C++ ist echt anstrengend zu kompilieren. Das schlägt sich dann auch ziemlich deutlich in der Übersetzungszeit nieder.
 
Zuletzt bearbeitet: (Ergänzung)
  • Gefällt mir
Reaktionen: KitKat::new() und foo_1337
foo_1337 schrieb:
Nein, kann man nicht. Und vieles auch nur sehr umständlich/langsamer.
c++ erweitert doch nur c, soweit ich mich erinnere und google mir auch bestätigt hatte auf die schnelle 🤷‍♀️
Ergänzung ()

andy_m4 schrieb:
Was wir dem Kram schon an BufferOverflows , SEGFAULTs usw. zu verdanken haben, weil jemand nicht aufgepasst hat, das geht auf keine Kuhhaut. Und das mit dem "nicht aufpassen" geht schneller als man denkt. :-)
dafür hast doch großteils deine sicherheits bits und features in cpu und OS .. (nagel mich nicht auf das genaue fest, aber es ist nichtmehr wie früher)
 
peter.hahn schrieb:
c++ erweitert doch nur c, soweit ich mich erinnere und google mir auch bestätigt hatte auf die schnelle 🤷‍♀️
Ja, es war mal als OO Erweiterung von C gedacht. Irgendwann in den früheren 80ern entstannt dann auch der CFront compiler, der im Wesentlichen den C++ Code in C übersetzt und compiliert hat. Mittlerweile sieht die Situation etwas anders aus, auch wenn die C++ Compiler nach wie vor in C geschrieben sind. Du kannst aber einfach gewisse Dinge, die in C möglich sind in C++ machen (und umgekehrt) bzw. nur mit massivem Aufwand und diversen Einbußen. Dazu kommt, dass es in gewissen Bereichen überhaupt nicht möglich ist, C++ Code zu schreiben, weil es keine Bibliotheken dafür gibt bzw. man die sich selbst schreiben müsste.

Erweiterung hört sich an wie "Ich kann damit alles so machen wie in C und noch viel mehr" und das ist schlicht falsch.


peter.hahn schrieb:
dafür hast doch großteils deine sicherheits bits und features in cpu und OS .. (nagel mich nicht auf das genaue fest, aber es ist nichtmehr wie früher)
Die schützen dich überhaupt nicht vor so etwas. W^X & Co schützen zwar vor diversen Dingen aber bei weitem nicht vor allem. Insbesondere nicht, wenn wie wild rumgecasted wird ohne Sinn und Verstand. Daher ist es auch gut, dass es Sprachen wie Rust gibt.
 
peter.hahn schrieb:
Du kannst nicht Ram Bereiche schreiben/lesen, die andere Programme nutzen.. was soll es denn sonst sein...
Super. Sowas ist doch überhaupt nicht notwendig und darum geht es auch nicht. Einfaches Beispiel: perl -e 'print(("A" x 100 . "\x{00}") x 50)' | sudo -i
Und du warst root. Behoben in sudo 1.8.31
Ursache: Buffer Overflow in getln() in tgetpass.c.
Hier der Fix dazu: https://github.com/sudo-project/sudo/commit/fa8ffeb17523494f0e8bb49a25e53635f4509078
Wie du siehst, kleine Änderungen, die fatale Folgen haben.

Und btw: Als root kann ich soviel in den Ram Bereichen (auch kmem) machen, wie ich will. Und wieviel software läuft nach wie vor als root...
 
  • Gefällt mir
Reaktionen: Arc Angeling
andy_m4 schrieb:
Das kann man so nicht unbedingt sagen. Gerade die Geschwindigkeitssache stimmt so überhaupt nicht mehr. Das war früher noch anders wo es keine ausgereiften C++-Compiler gab. Da hat man ja C++ erst mal nach C compiliert und dieses Ergebnis dann erst durch nen C-Compiler gejagt und solche Geschichten.
Aber all dies ist jetzt schon 30 Jahre her.

Was aber geblieben ist, ist ein Geschwindigkeitsunterschied zwischen nem C Compiler und nem C++ Compiler.
C++ ist echt anstrengend zu kompilieren. Das schlägt sich dann auch ziemlich deutlich in der Übersetzungszeit nieder.
So sehe ich das auch. Man muss schon sehr genau hinschauen, um Dinge zu finden, die in C möglich sind, aber nicht in C++. Ja, "const" ist nicht ganz das gleiche und C++ hat ein strengeres Typsystem (Beispiele). Aber man kann im Grunde in C++ genauso programmieren wie in C und nur wenige ausgewählte C++-Features nutzen. Genau das wird oft im Embedded-Bereich gemacht.

Und einen Geschwindigkeitsvorteil von C sehe ich tatsächlich auch nicht mehr. Ein erheblicher Teil von C++ sind schließlich Compile-Time-Features. Nicht umsonst wird Software für Hochfrequenzhandel an Wertpapierbörsen, wo jede Mikrosekunde bares Geld wert ist, oft in C++ geschrieben.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Arc Angeling und KitKat::new()
@andy_m4 @feynman Mit langsam meinte ich tatsächlich das erzeugen von Code. War auf das "machen" vom Vorzitat bezogen. Etwas blöde Wortwahl. Klar ist C++ nicht per-se langsamer als C. In vielen Fällen sogar schneller. Genau so wie javascript nicht per-se langsamer oder schneller als C/C++ ist. Es kommt immer auf den individuellen Use-Case an und vor allem wie das ganze implementiert wird.
Das Ding ist halt, dass du in gewissen Dingen mit wesentlich C schneller zum Ziel kommst als mit C++. (Und umgekehrt natürlich auch). Ich wollte nur das Zitat nicht so stehen lassen, wie es da stand, weil es so einfach nicht stimmte. Und miesen Code kannst du natürlich auch in jeder Sprache schreiben. In C geht es halt deutlich "einfacher" und hat oft fatalere Folgen.
 
foo_1337 schrieb:
Und du warst root.
finde den Fehler...
du kannst auch sudo machen bei rm -r /* was nur dumm ist und keine Sicherheitslücke war.

und mein Beispiel kam von Windows. OS sollte aber auch egal sein. Aber ja, nimm Sicherheitslücken + sudo + schwachfug code und nimm das als Argument ... sehr gut 👍
das oben kann man auch eingeben ... gab genug dumme witze darüber, und alles ab root (externe platten etc) war dann bei etlichen dummen menschen weg bei ihrem Mac
 
andy_m4 schrieb:
Aber es hat schon eine bevorzugte Art sich programmieren zu lassen.
Finde ich nicht. C++ hat irgendwie gar nichts bevorzugtes. Nichtmal in der STL. C++ scheint ein Haufen zu sein in dem man reingeschmissen hat was nützlich erscheint.

andy_m4 schrieb:
Generell kannst Du sowieso in jeder Sprache alles machen. Du kannst Dir in C++ auch nen Garbage Collector bauen und für Deine C++ Programme benutzen. Trotzdem würde niemand auf die Idee kommen C++ als GC-Sprache zu sehen.
Ich habe auch nicht behauptet, dass C++ auf funktional spezialisiert ist. In C++ kannst du pure Funktionen aber so einfach schreiben wie andere Konstrukte in C++.
Da muss man keinen nennenswerten Aufwand reinstecken. Daher ist dein Vergleich mit C++ also GC-Sprache absolut daneben.

andy_m4 schrieb:
Worum es mir ging ist, wozu einem die Sprache quasi ermuntert zu benutzen. Welche Vorgehensweise also idiomatisch ist. Und dementsprechend sehen dann auch die Programme völlig unterschiedlich aus.
Eben C++ ermuntert zu nichts - und entsprechend Variationen gibt es sogar innerhalb der Programmiersprache. Arbeitest du an einem Projekt und denkst deswegen C++ zu können, stehst du an anderen C++-Projekten gegebenenfalls also Programmieranfänger da.
andy_m4 schrieb:
Brauchen es aber auch nicht, weil dort eh Rekursion nicht im größeren Umfang eingesetzt wird.
Brauchen ist relativ - nur, weil man nicht permanent rekursive Code schreibt, möchte man natürlich den rekursive Code den man schreibt genauso gut optimiert haben.
Damit stellen sich nur die Fragen: ist genügend Geld für die Optimierung da, und ist der Zeitverlust beim Kompilieren tollerabel?

Bei erzwungener funktionaler Programmierung ist es dagegen ein Deal breaker, weil man sonst performancemäßig total im Eimer wäre.
 
  • Gefällt mir
Reaktionen: peter.hahn
peter.hahn schrieb:
finde den Fehler...
du kannst auch sudo machen bei rm -r /* was nur dumm ist und keine Sicherheitslücke war.

und mein Beispiel kam von Windows. OS sollte aber auch egal sein. Aber ja, nimm Sicherheitslücken + sudo + schwachfug code und nimm das als Argument ... sehr gut 👍
Du würfelst verschiedene Dinge zusammen. Oben behauptest du, dass der Kernel + CPU vor Buffer Overflows schützen würden. Und das ist falsch. Dein rm Beispiel ist unpassend, da dies keine Sicherheitslücke ist. Und auch dein root Argument ist falsch: Ja, als root darf ich alles und das ist gewollt. Aber ein daemon, der als root läuft, soll in der Regel einen gewissen Zweck erfüllen. Wenn hier nun ein Buffer Overflow, bestenfalls über tcp/udp remote ausgenutzt werden kann, ist es halt essig.
Und wegen "schwachfug code": Genau darum ging es doch in der Diskussion.
 
  • Gefällt mir
Reaktionen: KitKat::new()
peter.hahn schrieb:
c++ erweitert doch nur c
Na nicht ganz.
Es heißt ja immer, das C eine Untermenge von C++ ist. Im Großen und Ganzen stimmt das auch. Aber eben nicht perfekt. Es gibt da durchaus mehr oder weniger subtile Unterschiede. Also einfach ein C-Programm nehmen und durch nen c++ schicken wird nicht immer funktionieren.

Der wichtigere Aspekt ist aber, das man C++ nicht als Erweiterung von C betrachten soll was dazu führt, das man C und C++-Code mischt wobei schnell mal komische Sachen passieren.
Was man heutzutage unter modernen C++ versteht hat hat nicht mehr viel mit dem zu tun, was man unter C so üblicherweise macht. Und man sollte es auch vermeiden beide Sprachen zu mischen.

KitKat::new() schrieb:
Finde ich nicht. C++ hat irgendwie gar nichts bevorzugtes. Nichtmal in der STL. C++ scheint ein Haufen zu sein in dem man reingeschmissen hat was nützlich erscheint.
Da ist durchaus was dran.
Ich glaub, die einzige Bedingung dafür das etwas in den C++ Standard schafft ist, das es zero-cost sein muss. Wenn das erfüllt ist, landet jede noch so absonderliche Abstrusität früher oder später in C++ :-)
Begründet wird das ja auch damit, das man dem Programmierer die Freiheit geben möchte zu nutzen, was er nutzen möchte.
Das führt aber auch leider dazu, das C++ eine komplexe Sprache wird. So komplex, das sie keiner mehr überblickt und damit jeder so sein eigenes Subset an C++ schreibt, wie Du ja selbst weißt.

KitKat::new() schrieb:
Ich habe auch nicht behauptet, dass C++ auf funktional spezialisiert ist.
Ich habe auch nicht behauptet das Du das behauptet hast.
Ich wollte nur damit klarstellen, das jede Sprache zu einem gewissen Stil ermuntert.
Du wirst halt viel öfter sehen das in einer funktionalen Sprache (wie z.B. Racket) auch tatsächlich funktional programmiert wird als in C++
Mehr wollte ich eigentlich auch gar nicht zum Ausdruck bringen.

KitKat::new() schrieb:
Eben C++ ermuntert zu nichts - und entsprechend Variationen gibt es sogar innerhalb der Programmiersprache.
Ja. Kann man so sehen, wie oben von mir bereits angedeutet. Insofern komme ich Dir da ein Stück entgegen. :-)

KitKat::new() schrieb:
Damit stellen sich nur die Fragen: ist genügend Geld für die Optimierung da, und ist der Zeitverlust beim Kompilieren tollerabel?
Vor allem weil C++ Compiler eh schon zum erbrechen langsam sind. :-)

foo_1337 schrieb:
Oben behauptest du, dass der Kernel + CPU vor Buffer Overflows schützen würden.
Wobei es schon Situationen gibt, wo das der Fall ist. Zu DOS-Zeiten war das gar kein Problem und Speicherbereiche des Systems reinzuschreiben. Heute "sieht" jeder Prozess nur seinen eigenen Adressraum und hat gar nicht die Möglichkeit "einfach so" fremden Code zu beeinflussen. Und das, weil die Systeme Prozesse mit Hilfe der MMU der CPU abschirmen. :-)

Ein bisschen Recht hat er also schon. :-)
 
Sorry, hat er nicht. Ich rolle das nochmal kurz auf:

andy_m4 schrieb:
Was wir dem Kram schon an BufferOverflows , SEGFAULTs usw. zu verdanken haben, weil jemand nicht aufgepasst hat, das geht auf keine Kuhhaut. Und das mit dem "nicht aufpassen" geht schneller als man denkt. :-)
peter.hahn schrieb:
dafür hast doch großteils deine sicherheits bits und features in cpu und OS .. (nagel mich nicht auf das genaue fest, aber es ist nichtmehr wie früher)
Und das ist schlicht falsch. Egal ob unter DOS, Linux, xBSD, macOS oder Windows.

Er hat es so hingestellt, als gäbe es die Bufferoverflows nur wenn jemand den Speicherbereich eine anderen Programmes überschreibt. Und dem ist halt nicht so. Es reicht völlig aus, wenn den Mist in seinem eigenen Sumpf macht. Und je nachdem, wie priviligiert dieser Kram ist, ist der Schutz des Kernels auch früher oder später dahin.

Ist auch nach wie vor extrem einfach, einen segfault zu provozieren:

Code:
% echo "main(){raise(11);}" >foo.c
% cc -o foo.c 2>/dev/null
% ./a.out
Segmentation fault: 11
%
 
Zuletzt bearbeitet von einem Moderator:
  • Gefällt mir
Reaktionen: andy_m4
foo_1337 schrieb:
Oben behauptest du, dass der Kernel + CPU vor Buffer Overflows schützen würden. Und das ist falsch
nein, ist es nicht!
weil du kommst dann mit einer Sicherheitslücke, die dafür ausgenutzt werden muss, und für die es einen Fix gibt!

sowie etwas als SUDO ausführen, was man so auch nur sehr überdacht macht, weil SUDO einfach so mächtig ist!

und mein beispiel ist doof weil keine Sicherheitslücke? sie zeigt doch nur, dass SUDO sehr gefährlich sein kann, auch ohne zusätzliche Sicherheitslücke, und daher dein Argument mit über allokierten Ram hinaus blödsinn machen.. in andere Programme hinein.. heute in 99,9% der Fälle gar nicht mehr passieren kann..
Zumindest nicht, wenn man es massivst darauf anlegt.
Das war früher ganz anders!
 
Du hast es nicht verstanden. Der Buffer overflow in sudo war ein reines Beispiel. Wie viele soll ich dir noch geben? Wieso willst du nicht verstehen, dass dich weder der kernel noch die CPU vor so etwas schützen können? Selbst gute analyzer wie coverity können dich nicht komplett davor schützen.
Mal schauen, vielleicht hab ich ja noch die muße, dir mal ein besseres Codebeispiel als den segfault oben zu schreiben.
 
foo_1337 schrieb:
Der Buffer overflow in sudo war ein reines Beispiel. Wie viele soll ich dir noch geben?
ein sinnvolles, und nicht eins das auf SUDO und einer inzw. behobenen Sicherheitslücke besteht?!
ich hab dir auch beispiele genannt, wo es heute nicht mehr so passieren kann wie noch vor vielen Jahren, als es keine standard Schutzmaßnahmen dagegen gab die im Hintergrund aufpassen.

Ich glaub du willst es einfach nicht verstehen.
Ergänzung ()

foo_1337 schrieb:
Ist auch nach wie vor extrem einfach, einen segfault zu provozieren:
ja! und dass es diese Meldung gibt ist doch Schutz! die sagt, "lass das du idiot" und sonst passiert nichts.
ansonsten wäre keine Warnung gekommen und plötzlich wäre irgendwas passiert.. dieser fehlende Schutz wurde früher öfters als einfallstor für schadsoftware genutzt.
Ergänzung ()

foo_1337 schrieb:
Es reicht völlig aus, wenn den Mist in seinem eigenen Sumpf macht.
ja, im eigenen Teil des Speichers doch auch irgendwie ok, da kann man rumtricksen wie man lustig ist.
aber man zerstört nicht das laufende OS oder stört andere Programme.
 
Zuletzt bearbeitet:
peter.hahn schrieb:
ein sinnvolles, und nicht eins das auf SUDO und einer inzw. behobenen Sicherheitslücke besteht?!
https://www.openwall.com/lists/oss-security/2019/08/28/3
Bitteschön.


peter.hahn schrieb:
ja! und dass es diese Meldung gibt ist doch Schutz! die sagt, "lass das du idiot" und sonst passiert nichts.
ansonsten wäre keine Warnung gekommen und plötzlich wäre irgendwas passiert.. dieser fehlende Schutz wurde früher öfters als einfallstor für schadsoftware genutzt.
Challenge accepted. Beispiel Bufferoverflow inkl. Exploit folgt.

peter.hahn schrieb:
ja, im eigenen Teil des Speichers doch auch irgendwie ok, da kann man rumtricksen wie man lustig ist.
aber man zerstört nicht das laufende OS oder stört andere Programme.
Nein, ist es nicht. Auf keinen Fall!! Wie kommst du denn darauf? Siehe z.B. die Dovecot Lücke oben:
This vulnerability allows for out-of-bounds writes to objects stored on
the heap up to 8096 bytes in pre-login phase, and 65536 bytes post-login
phase, allowing sufficiently skilled attacker to perform complicated
attacks that can lead to leaking private information or remote code
execution
.

"Sie haben ihr Ziel erreicht." Völlig egal, ob man damit anderen Programmen in die Quere kommt, oder nicht. Ich kann mails lesen und mit den privilegien des Dovecot users Dinge auf der Kiste anstellen.
 
Zurück
Oben