Cyblord -. schrieb: > > Allerdings kostet die Überprüfung zur Laufzeit eben CPU Zeit und > Speicher. Irgendwo müssen die Grenzen eingetragen sein, es muss ein Code > laufen der diese Grenzen bei jedem Zugriff prüft. Sicherheitsgurte gibts > hier nicht umsonst. Und grade im Embedded Umfeld will niemand > "versteckten" Code der schnell mal 30% der Laufzeit in einer Schleife > mit Arrayzugriffen ausmachen kann. Klar. Drum ist es ja praktisch, dass es hier undefiniertes Verhalten gibt, dass den Implementierungen die Freiheit gibt, die unterschiedlichen Anforderungen verschiedener Programmierer umzusetzen.
Stefan ⛄ F. schrieb: > C ist quasi die Ente/Käfer/Trabbi unter den Automobilen. Nicht schlecht, > aber auch nicht deppensicher. Wären da ein Donkervoort oder Caterham nicht passendere Autovergleiche? Ich mein, für besondere Fahrleistungen sind Enten, Trabbis und Käfer ja nun nicht gerade bekannt.
Jemand schrieb: > Wären da ein Donkervoort oder Caterham nicht passendere Autovergleiche? Die kenne ich nicht. Wenn ich mir die Fotos bei Google anschaue: nein, so cool hat C noch nie ausgesehen. Obwohl - die offene Karosserie passt. > Ich mein, für besondere Fahrleistungen sind Enten, > Trabbis und Käfer ja nun nicht gerade bekannt. C läuft auf prima mit kleinem "Motor". Ich musste mal Java auf einem 386er nutzen, das war super ätzend.
Stefan ⛄ F. schrieb: > Jemand schrieb: >> Wären da ein Donkervoort oder Caterham nicht passendere Autovergleiche? > > Die kenne ich nicht. Wenn ich mir die Fotos bei Google anschaue: nein, > so cool hat C noch nie ausgesehen. Obwohl - die offene Karosserie passt. Paßt auch sonst vieles: keine Servolenkung, kein Bremskraftverstärker, kein ABS oder ASR, wie Donkervoort auf der alten Seite schrieb: "the driver is in charge". >> Ich mein, für besondere Fahrleistungen sind Enten, >> Trabbis und Käfer ja nun nicht gerade bekannt. > > C läuft auf prima mit kleinem "Motor". > > Ich musste mal Java auf einem 386er nutzen, das war super ätzend. Wärgs, mein herzliches Beileid!
Stefan ⛄ F. schrieb: > Ich musste mal Java auf einem 386er nutzen, das war super ätzend. Was Pointer in C sind, sind Threadpools in Java. Man muss schon wissen was man tut ... LG, Sebastian
Philipp Klaus K. schrieb: > Wer diese Überprüfung will, kann das bei GCC und LLVM per > -fsanitize=array-bounds machen. Leider funktioniert die nur, wenn direkt auf dem Array gearbeitet wird und nicht, wenn es an eine Funktion übergeben wird, wo es zum Pointer verflacht. Letzteres ist aber der häufigere Fall.
Stefan ⛄ F. schrieb: > Jemand schrieb: >> Wären da ein Donkervoort oder Caterham nicht passendere Autovergleiche? > > Die kenne ich nicht. Wenn ich mir die Fotos bei Google anschaue: nein, > so cool hat C noch nie ausgesehen. Obwohl - die offene Karosserie passt. > >> Ich mein, für besondere Fahrleistungen sind Enten, >> Trabbis und Käfer ja nun nicht gerade bekannt. > > C läuft auf prima mit kleinem "Motor". Caterham und Donkervoort sind Sohn und Stiefsohn des legendären Lotus Seven, und schon der war bekannt dafür, trotz des im Vergleich zur Konkurrenz geringeren Hubraums abzugehen wie Schmidts Katze. Wie hat er das gemacht? Durch Light-Weight. Auch das passt ganz gut zu C :)
Yalu X. schrieb: > Wie hat er das gemacht? Durch Light-Weight. > Auch das passt ganz gut zu C Ja. Man lässt alle Schnörkel und Anbauten weg, die man weglassen kann. Sheeva P. schrieb: > wie Donkervoort auf der alten Seite schrieb: "the > driver is in charge". Wer das nicht gut findet: völlig OK, es gibt andere Programmiersprachen mit anderen Zielen.
Nop schrieb: > Philipp Klaus K. schrieb: > >> Wer diese Überprüfung will, kann das bei GCC und LLVM per >> -fsanitize=array-bounds machen. > > Leider funktioniert die nur, wenn direkt auf dem Array gearbeitet wird > und nicht, wenn es an eine Funktion übergeben wird, wo es zum Pointer > verflacht. Letzteres ist aber der häufigere Fall. Auch ein Grund, warum C oder "das C in C++" nicht verwenden sollte. Auch wer keine einzige Klasse schreibt, kann doch Vorteile aus C++ ziehen. Und mit einem Funktions-template vermeidet man das "decay".
Wilhelm M. schrieb: > Auch wer keine einzige Klasse schreibt, kann doch Vorteile aus C++ > ziehen. Und mit einem Funktions-template vermeidet man das "decay". Das ist nun wirklich unsinn. In C++ nutzt man std::vector und std::array und hat das Problem mit dem decay gar nicht erst.
mh schrieb: > Wilhelm M. schrieb: >> Auch wer keine einzige Klasse schreibt, kann doch Vorteile aus C++ >> ziehen. Und mit einem Funktions-template vermeidet man das "decay". > > Das ist nun wirklich unsinn. Sehe ganz und gar nicht so. Dann hast Du mich falsch verstanden. Viele wollten kein C++ benutzen, oder können es nicht wegen unterschiedlichster Gründe. Etwa weil sie die stdlib nicht auf ihrer Plattform haben oder nutzen wollen/können. Mir ging es nur darum. > In C++ nutzt man std::vector und std::array > und hat das Problem mit dem decay gar nicht erst. s.o., wenn man das nutzen will oder kann. Natürlich ist es klar, dass man das nutzt, wenn man C++ umfänglich verwendet. Hier geht es aber um "das C im C++".
Wilhelm M. schrieb: > Und mit einem Funktions-template vermeidet man das "decay". Allerdings hat man dann für jede Array-Größe, mit der man die Funktion nutzt, eine eigene Instanz dieses Templates. Und die Größe muss zur Compilezeit feststehen.
:
Bearbeitet durch User
Rolf M. schrieb: > Allerdings hat man dann für jede Array-Größe, die im Programm vorkommt, > eine eigene Instanz dieses Templates Und das ist selbst in µC Umgebungen kein Problem, der befürchtete "bloat" ist wesentlich geringer, als man gemeinhin annimmt. Rolf M. schrieb: > Und die Größe muss zur Compilezeit > feststehen. Das stimmt: VLA sind C, aber:
1 | const size_t n{10}; |
2 | int a[n]{}; |
ist auch in C++ ok, wobei GCC "echte" VLAs als extension möglich macht.
Wilhelm M. schrieb: > Rolf M. schrieb: >> Und die Größe muss zur Compilezeit >> feststehen. > > Das stimmt: VLA sind C, aber: Seit C11 aber nur noch optional. > const size_t n{10}; > int a[n]{}; > > ist auch in C++ ok, Aber das ist trotzdem eine zur Compilezeit feststehende Größe. Einer Funktion, die einen Zeiger übergeben bekommt, ist es dagegen vollkommen egal, was das für ein Array ist. Man muss ihr natürlich die Größe mitteilen.
Rolf M. schrieb: > Aber das ist trotzdem eine zur Compilezeit feststehende Größe. Das habe ich ja auch oben unterschieden. Rolf M. schrieb: > Man muss ihr natürlich die Größe > mitteilen. Und das macht man am besten in einem 'struct'. Ja, und dann ist der Weg zu std::array<> oder etwas ähnlichem (falls man stdlib nicht benutzen will/kann) ja nicht mehr weit.
Wilhelm M. schrieb: > Auch ein Grund, warum C oder "das C in C++" nicht verwenden sollte. Es geht hier auch um C. Es ist echt anstrengend, deine C++ lobhudelei andauernd und an jeder unpassenden Ecke. Bekommst Geld dafür?
900ss schrieb: > Wilhelm M. schrieb: >> Auch ein Grund, warum C oder "das C in C++" nicht verwenden sollte. > > Es geht hier auch um C. Sehr passend: ... auch ... > Es ist echt anstrengend, deine C++ lobhudelei > andauernd und an jeder unpassenden Ecke. Bekommst Geld dafür? Das ist keine Lobhudelei, sondern einfach der Hinweis darauf, das es besser geht (in diesem Fall). Da ja oben sogar über andere Programmiersprachen und auch über hypothetische Erweiterungen von C diskutiert wird, sollte es doch möglich sein, auch den Hinweis auf cherry-picking aus C++ möglich sein, oder?
Yalu X. schrieb: > Caterham und Donkervoort sind Sohn und Stiefsohn des legendären Lotus > Seven, und schon der war bekannt dafür, trotz des im Vergleich zur > Konkurrenz geringeren Hubraums abzugehen wie Schmidts Katze. Wie hat er > das gemacht? Durch Light-Weight. Auch das passt ganz gut zu C :) Sehr richtig, Colin Chapman -- der Gründer von Lotus -- hat sehr konsequent auf Leichtbau gesetzt und wird mit Aussagen wie "Any car which holds a whole race is too heavy" und "Adding Power makes you faster on the straights. Subtracting weight makes you faster everywhere" zitiert. Leider hat das dazu geführt, daß die Formel1 einige sehr heftige Unfälle erleben mußte, die bekanntesten davon vermutlich die Crashes von Martin Donelly 1990, Jochen Rindt 1969 in Barcelona, sowie im darauf folgenden Jahr der tödliche Unfall von Jochen Rindt -- allesamt, weil wichtige Teile an ihren Fahrzeugen gebrochen waren.
Lothar schrieb: > Viele glauben das geht nur in C++ aber es geht auch in C - und ist in > der Embedded Programmierung sogar teilweise vorgeschrieben - kein > malloc() > > Hier ein Beispiel: C struct wie C++ Klasse Schönes Beispiel von dir, super! Ich geb dir recht, grundsätzlich kann man mit Stack-Kopien schön hantieren und kann möglicherweise auch eine Aufblähung in zu große Structs vermeiden (was die Sache u.U. testbarer machen kann). In Verbindung mit Designated Initializers (C99) wirds fast lesbar: struct DATA test = { .x = 1 }; Dennoch kosten Funktionsrahmen beim Aufruf potentiell mehr und die Rücksprunge ebenso durch entweder Daten-Kopiererei oder -Verschiebung. Einen richtigen Vorteil sehe ich eigentlich nicht gegenüber einem "struct DATA restrict *const" ^^
db8fs schrieb: > Dennoch kosten Funktionsrahmen beim Aufruf potentiell mehr und die > Rücksprunge ebenso durch entweder Daten-Kopiererei oder -Verschiebung. Hat jemand Erfahrung mit RVO in C? Ist das von Standard ausgeschlossen? Ich habe eben etwas getestet und konnte gcc nicht dazu bringen eine Kopie mit RVO zu vermeiden.
mh schrieb: > db8fs schrieb: >> Dennoch kosten Funktionsrahmen beim Aufruf potentiell mehr und die >> Rücksprunge ebenso durch entweder Daten-Kopiererei oder -Verschiebung. > > Hat jemand Erfahrung mit RVO in C? Ist das von Standard ausgeschlossen? > Ich habe eben etwas getestet und konnte gcc nicht dazu bringen eine > Kopie mit RVO zu vermeiden. Ok, clang hat keine Probleme RVO zu nutzen.
mh schrieb: > db8fs schrieb: >> Dennoch kosten Funktionsrahmen beim Aufruf potentiell mehr und die >> Rücksprunge ebenso durch entweder Daten-Kopiererei oder -Verschiebung. > > Hat jemand Erfahrung mit RVO in C? Ist das von Standard ausgeschlossen? Warum sollte es? In C++ muss es ja nur deshalb explizit erlaubt sein, weil das Kopieren eines Objekts "side effects" haben kann - über Konstruktor und Destruktor, und wenn die Kopie nicht gemacht wird, finden die nicht statt. Das gibt es bei C aber nicht, und daher ist es von der "as if"-Rule abgedeckt. > Ich habe eben etwas getestet und konnte gcc nicht dazu bringen eine > Kopie mit RVO zu vermeiden. Also ich hab's grad probiert, und es funktioniert bei mir mit gcc, wenn man mindestens mit -O1 optimiert.
Rolf M. schrieb: > mh schrieb: >> db8fs schrieb: >>> Dennoch kosten Funktionsrahmen beim Aufruf potentiell mehr und die >>> Rücksprunge ebenso durch entweder Daten-Kopiererei oder -Verschiebung. >> >> Hat jemand Erfahrung mit RVO in C? Ist das von Standard ausgeschlossen? > > Warum sollte es? In C++ muss es ja nur deshalb explizit erlaubt sein, > weil das Kopieren eines Objekts "side effects" haben kann - über > Konstruktor und Destruktor, und wenn die Kopie nicht gemacht wird, > finden die nicht statt. Das gibt es bei C aber nicht, und daher ist es > von der "as if"-Rule abgedeckt. Das ist mir klar. Deswegen hab ich gefragt, ob es ausgeschlossen wird. Rolf M. schrieb: >> Ich habe eben etwas getestet und konnte gcc nicht dazu bringen eine >> Kopie mit RVO zu vermeiden. > > Also ich hab's grad probiert, und es funktioniert bei mir mit gcc, wenn > man mindestens mit -O1 optimiert. Ok RVO mit nem rvalue macht gcc bei mir auch. Hast du zufällig mal NRVO also mit nem RVO mit nem lvalue getestet?
1 | struct Data { |
2 | int b[64]; |
3 | };
|
4 | struct Data make_Data(int a) { |
5 | struct Data tmp; |
6 | for(int i=0; i<64; ++i) { |
7 | tmp.b[i] = a + i; |
8 | }
|
9 | return tmp; |
10 | }
|
mh schrieb: > Ok RVO mit nem rvalue macht gcc bei mir auch. Hast du zufällig mal NRVO > also mit nem RVO mit nem lvalue getestet? Ja. Aber ich glaub, ich bin einer Optimierung aufgesessen.
Arduino Fanboy D. schrieb: > Eigentlich ist es sogar noch schlimmer:
1 | char *t1 = "Beispiel"; |
2 | char *t2 = "Beispiel"; |
3 | t2[0] = '*'; |
Das erzeugt unter Betriebssystemen wie Linux in der Regel einen Programmabbruch aka Core Dump. Dass Du es unterlässt, t2 als non-const-Pointer anzugeben, hindert den Compiler noch lange nicht daran, den konstanten String "Beispiel" in das Text-Segment zu legen. Kommt dieser String mehrfach im Code vor, optimiert der Compiler das und erzeugt nur einen String im Text-Segment. Das darf er, da Zeichenketten nicht beschreibbar sind. Und damit zeigen t1 und t2 auf denselben String. Die Zeile
1 | t2[0] = '*'; |
versucht dann, ins Text-Segment zu schreiben. Das gibt unter Linux (und auch anderen Betriebssystemen) einen harten Programm-Abbruch. Schreib einfach:
1 | char t1[] = "Beispiel"; |
2 | char t2[] = "Beispiel"; |
und Dein "Problem" löst sich in Luft auf.
:
Bearbeitet durch Moderator
Frank M. schrieb: > und Dein "Problem" löst sich in Luft auf. Das ist nicht mein Problem, und zudem erwähne ich wohl schon, dass es eine Ausnahmen werfen kann, oder sonst ein Drama generieren. Da eben die Ablage des Strings "Implementatition Defined" ist und der schreibende Zugriff dann ein "Undefined Behavior" nach sich zieht. Eigentlich diente es eher der Vorführung, dass Pointer und Arrays eben NICHT das gleiche sind. Es gibt Äquivalenzen, aber mehr auch nicht. Da schienen mir einige der Vorposter falsch abgebogen zu sein.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.