C tut weh!

Oct 10, 2019 53 Replies
Jump to replies (53)

C_hurts sounds in German like: Tooths hurts ( C_tut_weh :)



So here is the pain: Hier ist der Schmerz:



(*(void(*)())0)()



ok, ein böses Beispiel, wie übel C sein kann.



Ich weiss was es macht :) Wissen die C-progger das auch? Sogar sinnvoll auf vielen CPUs.



Hint: In Forth 2 Worte (auch interaktiv) und in Z80 Assembler 2 Befehle. Beides schon oft gebraucht :p



In HW eine Taste und/oder ein WW-Pfosten Pärchen. Auch oft gebraucht :)



Nun auf, ich warte :o


Saludos (an alle Vernünftigen, Rest sh. sig) Wolfgang


Hi,

ich habe zwar schon eine ganze Weile kein C mehr geschrieben aber ich würde vermuten, eine Funktion mit Adresse 0. Also sozusagen ein Reboot "auf manchen Maschinen"?

Viele Grüße Ronald

Ja. Hat der Wolfgang halt unnötig kompliziert hingeschrieben, Funktionszeiger müssen in C nicht explizit dereferenziert werden. Weiß er aber vermutlich nicht, weil er halt kein C kann.

Undefiniertes Verhalten. Alles kann, nichts muss.

Viele Grüße, Johannes

Am 10.10.2019 um 12:42 schrieb Wolfgang Allinger:

^^^^^^ Das Word gibt es IMHO nicht.

tooth: der Zahn. Mehrzahl: teeth

Was Du meinst, heißt "toe", Mehrzahl "toes"

Dein Zeh ist also auf Englisch der "tooth", ja? Du kannst also nicht nur kein C, sondern auch kein Englisch.

[...]> Hint:

Also dein Beispiel ist dafür, wie übel C ist, aber in Forth kann man dasselbe machen und in Z80 Assembler ja auch. Grübelgrübel, sind die Sprachen dann nach deiner Logik nicht genauso übel? Bissl schlechtes Argument gegen C, dass du dir da rausgesucht hast, merkste selber, oder?

Man kann ja viel berechtigte Kritik an C üben, aber du stümperst sogar beim plumpen Stänkern derart, dass es peinich ist.

Viele Grüße, Johannes

Am 10.10.2019 um 12:42 schrieb Wolfgang Allinger: > C_hurts sounds in German like: Tooths hurts ( C_tut_weh :)

Meinst Du nicht toe hurts?

Error: expected a ";"

Wozu sind Compilerfehler sinnvoll?

Falls Du den Sprung an Adresse 0 meinst, der ist nur sinnvoll wenn das Programm dort beginnt.

Bei meiner aktuellen CPU dürfte es einen hard fault erzeugen. Und den mag ich überhaupt nicht.

"Wolfgang Allinger" snipped-for-privacy@spambog.com schrieb im Newsbeitrag news:EvbIW$ snipped-for-privacy@allinger-307049.user.uni-berlin...

Im Gegenteil, ein schönes Beispiel wie nützlich C ist, und ich habe es auch schon benutzt um RESET und andere Vektoren auf Controllern auszulösen.

Hm ich kenne nicht viele CPUs, bei dem ein Sprung an 0 auch direkt die ganze Peripherie resettet. Ohne den ist ein "Soft-Reset" bei vielen SoCs extrem witzlos, wenn alles was nicht gerade der Kern ist in einem undefinierten Zustand hängt.

Gruß, Johannes

Johannes Bauer schrieb:

Es wird IMO nicht kritisiert, dass man die Adresse 0 aufrufen kann, sondern die dafür klammerreiche Syntax. Ich weiß zwar nicht, wie dass in Forth aussieht oder Z80-Assembler, aber sinnvoll kann das allemal sein und ist nicht das Übel, was du hier zu erkennen glaubst.

'Schön' ist z.B die C-Deklaration der Unix signal(2) Funktion, wenn man keinen typedef nimmt:

void (*signal(int signum, void (*handler)(int)))(int);

Mit typedef siehts dann wieder lesbarer aus:

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

- Heinz

Ah, okay! Dann ist die Kritik ja tatsächlich noch blöder als ich dachte und zieht sich ausschließlich an Oberflächlichkeiten hoch.

Moment, ich finde das nicht übel. Wolfgang findet es übel.

Klar ist es nützlich, dass man solche Manipulationen machen kann (und quasi eine rein numerische Adresse zu einem Funktionszeiger casten) -- aber aus Sicherheitsaspekten ist es halt schon eher schlecht, dass die Sprache soetwas überhaupt zulässt. Ist halt, wie bei jeder Informatik-Lösung, ein Kompromiss. Ich bin ganz glücklich mit C, ist noch von allen Optionen oft das geringste Übel.

Hmja, habe ich jetzt auch keine Probleme damit, aber ist vermutlich geschmackssache bzw die Frage, wie oft man sowas schon gesehen hat.

Das ist ja geradezu einfach :)

Viele Grüße, Johannes

Nein, die Konstruktion wird oft sinnvoll angewandt.

(* (void(*)())0 )()

Die Konstante 0 wird gecastet in einen Funktionspointer auf eine Funktion, die nichts retourniert. Dann wird dieser Funktionspointer explizit dereferenziert und die Funktion mit Adresse 0 aufgerufen.

Häufiger kommt so etwas vor: # define NEsp0ARR(S,A) (sizeof(((S*)0)->A)/sizeof(*((S*)0)->A))

Doch, und zwar KRISTALL klar:

"§6.5.3.2 Address and indirection operators" sagt:

"If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined."

Und dann noch eine Fußnote:

"Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer, [...]"

Da gibt es überhaupt keinen Zweifel, einen Nullpointer in C zu dereferenzieren ist definitiv undefiniertes Verhalten.

Schon klar.

Das Dereferenzieren ist undefiniertes Verhalten, auch wenn es Implementierungsabhängig üblicherweise das macht, was du beschreibst.

sizeof() ist ohnehin implementation defined, ganz unabhängig was man reinsteckt.

Viele Grüße, Johannes

Johannes Bauer schrieb:

Ja, er findet die Syntax dazu übel. Er zeigt aber nicht, wie es in Forth aussieht. In 8051 Assembler wär es so:

ljmp 0

In hosted Umgebungen (Unix, Windows ...) sehe ich auch kaum Anwendung dafür, aber bei Mikrocontrollern schon.

Ich arbeite z.Z mit den XMC Controllern von Infineon und die haben Routinen auf dokumentierten Adressen im ROM, die vom Programmiere genutzt werden können. Dafür ist der Cast eines Wertes in einen Funktionspointer sinnvoll.

- Heinz

Johannes Bauer schrieb:

Wobei sizeof vom Compiler ausgewertet wird und nicht zur Laufzeit. Deshalb wird da auch nichts wirklich dereferenziert.

- Heinz

Hm naja, für Linux Kernelprogrammierung kommt man z.B. um C nicht herum. Und ich hab auch schon Sachen für Hosted-Controller (z.B. Raspberry Pis oder so) in C geschrieben, um den ganzen bloatigen Overhead zu umgehen, der durch einen X-Server/Webbrowser/wie auch immer zu Stande kommt.

Aber klar, wenn Performance und Language-Bindings keine Rolle spielen, nehme ich auch viel lieber Python.

Ahja, richtig. Hatte ich auch mal bei Stellaris Cortex-M3s, die hatten safeRTOS im ROM und da war das genauso. Sehr praktische Sache.

Viele Grüße, Johannes

Aus reiner Neugier täte mich mal interessieren, wieso das irgendwie übel sein sollte.

MfG hjs

Am 10.10.2019 um 13:17 schrieb Werner Flügel:

IMO meint er eher wC, oder ganz schlimm Wc. [großes Weh am kleinen Zeh]

DoDi

Am 10.10.2019 um 14:40 schrieb Helmut Schellong:

Geht das nicht einfacher mit goto 0; ???

DoDi

Wenn schon, dann "goto *0;". Aber zum einen ist ein goto etwas anderes als ein Funktionsaufruf, also funktional nicht äquivalent, und zum anderen machst du damit ja Wolfgang's Narrativ kaputt, darf also nicht sein.

Gruß, Johannes

Es scheint übel, wenn einem ein Allingersches Realitätsverzerrungsfeld die Birne vernebelt.

Gruß, Johannes

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required