"Tipps" für optimales C???
-
Gibt es vielleicht irgendwo im Inet eine Zusammenfassung solcher Tipps???
lies dir regelmäßig Beiträge in dem Forum durch. Besonders wenn in den Threads Shade, Daniel E., Bashar oder Descartes posten, findet man oft ein paar interessante Dinge. Dann steht auch viel in den verschiedenen FAQs.
@PAD
ich glaub im Struppi, den du ja immer zitierst, steht warum Bjarne kein implizites casten von void* zu typisierten Pointern haben wollte.Ansonsten ist das ja auch nicht wirklich weiter schlimm, da man bei C++ ja eh kein malloc verwenden sollte. Wozu haben wir denn new?
-
Man könnte auch einfach 2 bis 3 Wochen de.comp.lang.c lesen. (Danach abbestellen nicht vergessen)
-
Folgendes Usenet Posting finde ich hierzu ganz passend:
From: "Richard Heathfield" complangc@eton.powernet.co.uk
Subject: Re: Why not cast malloc?
Message-ID: 01bf7633$364d2ba0$0e01a8c0@arc5.croydon#1/1
Newsgroups: comp.lang.cAndrew Jones luminous-is@home.com wrote in article
tkzp4.38012$45.2077485@news2.rdc1.on.home.com...
> I've read in a few threads here people saying that you shouldn't cast malloc's
> return in C. Why is this? I almost always cast, and never had a problem. I
> find it makes it easier for me to remember just what it was I was allocating
> memory for.We write code either because it has a positive benefit or because it
prevents something bad happening.In C, casting doesn't prevent anything bad happening. For char *p,
p = malloc(1000);
and
p = (char *)malloc(1000);
are equivalent - the cast doesn't do anything wonderful that we need in
order to be able to use the memory. So it has no positive benefit, and it
doesn't prevent anything bad happening. So why put it in?Now consider what happens if you have unaccountably forgotten to #include
<stdlib.h>.The line
p = malloc(1000);
will give you a diagnostic, because the compiler will have assumed, in the
absence of any other information, that malloc returns int, but here you are
trying to assign it as if it were a pointer.The line
p = (char *)malloc(1000);
may well /not/ give you a diagnostic. The cast assures the compiler that
all is well. You are, effectively, saying to the compiler "yes I know
malloc returns int, but - for reasons which make perfect sense to me but
which it's impossible to explain to you - I want to pretend it's a char *.
I know exactly what I'm doing, so trust me, it'll be fine".The compiler is now free to generate code on the assumption that malloc
returns int. Consider a system where sizeof(void== 8 but sizeof(int) ==
2. The compiler may store the result of the malloc call in a 16-bit
register rather than a 64-bit register. The consequences to your code could
be unfortunate.In this case, then, casting gives you no benefits, prevents no problems,
gives you /more typing/ to do, and potentially conceals a serious bug. So
why do it?> Anyone care to elaborate on why it seems to be such a no-no? (Or is it in the
> FAQ?)I trust this answer is elaborate enough for you. If not, let me know - I
have some oak veneer somewhere...
-
@kingruedi
Deswagen muss man ja in C++ explicit casten.
Wenn es da gut ist warum ist es dann in C schlecht.@Descartes Das Posting ist interessant und plausibel und das Argument ist gut bis sehr gut
Now consider what happens if you have unaccountably forgotten to #include <stdlib.h>.
Wenn ich auf oder für unterschiedliche Platformen programmiere ist es eigentlich das Argument nicht zu casten.
Für alle anderen Fälle, Dappigkeit (vergessen <stdlib.h>) gegen Lesbarkeit (cast) sollte jeder selber gegeneinander abwägen.
-
PAD schrieb:
Deswagen muss man ja in C++ explicit casten.
Wenn es da gut ist warum ist es dann in C schlecht.Eigentlich sind void-Zeiger in C++ immer 'schlecht'.
In C++ wird dem Programmierer aufgetragen, den korrekten Typ des void-Zeigers (worauf er eigentlich zeigt) zu kennen. Es ist ja zB so, dass Zeiger auf Integer nur auf Adressen die restlos durch sizeof(int) teilbar sind liegen können. Wenn der originale void* auf eine Adresse zeigt, die nicht von int* referenziert werden kann, so hat der Code UB, in C wie in C++. Ob dieser Unterschied in der Praxis irgendeine Relevanz hat ist natürlich die andere Frage: Tritt so ein Fehler auf (also ein void* kann nicht implizit in Typ* umgewandelt werden), so wird nach meiner Erfahrung nach einfach geschaut, welcher Typ links steht und dann wird gecastet. Naja, wenigstens kann sich C++ angeblich, dank dieser Änderung, getrost 'typensicher' nennen.
-
Daniel E. schrieb:
Es ist ja zB so, dass Zeiger auf Integer nur auf Adressen die restlos durch sizeof(int) teilbar sind liegen können.
Du meinst, das könnte so sein.
-
Hallo ersteinmal!
Ich habe mal gelesen, da mitlerweile sehr viele Leute Ihren C- Quelltext nicht immer mit einen reinen C-Compiler compilieren (sondern mit einen C/C++ Compiler), sollte man sich besser angewöhnen das malloc zu casten. C kommt auf jeden Fall auch ohne casten aus im Gegensatz zu C++.
Gruß
JoeF
-
JoeF schrieb:
Ich habe mal gelesen,
Irrelevant
JoeF schrieb:
Da mitlerweile sehr viele Leute Ihren C- Quelltext nicht immer mit einem reinen C-Compiler compilieren (sondern mit einen C/C++ Compiler),
Dann benutzen halt "sehr viele Leute" ihre Werkzeuge halt ganz einfach falsch.
Wer nur einen Hammer hat, behandelt jedes Problem wie einen Nagel.JoeF schrieb:
[Daher] sollte man sich besser angewöhnen das malloc zu casten. C kommt auf jeden Fall auch ohne casten aus im Gegensatz zu C++.
Aha. Sehr interessante Meinung.
Ich fasse mal zusammen, was du uns sagen möchtest:
Da mittlerweile sehr viele Leute ihre Schrauben mit einem Hammer einschlagen, statt sich mehrere Werkzuge zu bedienen, sollte man sich besser angewöhnen, Schrauben mit dem Hammer einzuschlagen. Schrauben kann man aber auch mit einem Schraubendreher eindrehen, im Gegensatz zu Nägeln.
-
Bashar schrieb:
Daniel E. schrieb:
Es ist ja zB so, dass Zeiger auf Integer nur auf Adressen die restlos durch sizeof(int) teilbar sind liegen können.
Du meinst, das könnte so sein.
Nein, wenn ich mir den Satz nochmal durchlese muss ich feststellen, absoluten Blödsinn geschrieben zu haben (ohne Kommafehler): Ich meinte selbstverständlich nicht 'liegen' sondern 'zeigen'. Und auch sonst sollte ich natürlich deutlicher unterstreichen, dass das nicht immer so sein muss, sondern nur ein frei erfundenes Beispiel war, richtig.
-
Schön das es auch hier immer Neu-mal-kluge Leute gibt.
Descartes schrieb:
Aha. Sehr interessante Meinung.
Ich fasse mal zusammen, was du uns sagen möchtest:
Da mittlerweile sehr viele Leute ihre Schrauben mit einem Hammer einschlagen, statt sich mehrere Werkzuge zu bedienen, sollte man sich besser angewöhnen, Schrauben mit dem Hammer einzuschlagen. Schrauben kann man aber auch mit einem Schraubendreher eindrehen, im Gegensatz zu Nägeln.
Schön das du weißt was ich euch sagen möchte: , irgendwie war von Hammer und Nägeln nie die Rede.
Ich habe ja nicht behauptet, dass es so gut ist.
Also nochmal: Wenn Autoren ein Buch schreiben, schreiben sie es oftmals für die breite Masse (also auch für Anfänger) und da C und C++ eng miteinander verwandt sind wollen sie (denke ich zumindestens) speziell den Anfänger nicht durcheinander bringen. Und du wirst mir wohl recht geben, dass die meisten nicht einen reinen C- Compiler benutzen (ich weiß du ja).
Um nun also Fehler vorzubeugen, mußt man malloc casten.Nohmal es sollte ja garkein Aufruf werden, absofort nur noch C++ Compiler zu benutzen, um ein C-Quellcode zu kompilieren, sondern nur der Versuch einer Erklärung warum so oft die Diskussion aufkommt wegen dem malloc und casten oder nicht.
Gruß
JoeF
-
wenn man denn mal malloc, calloc benutzt bleibt einem ja wohl ichts anderes übrig.
Das nutzen dieser verpönten funktionen ist immer dann interessant wenn man funktionierende Routinen oder
Libraries aus C in C++ weiterverwendet, man muß man im ersten Schritt "nur" die casts nachrüsten. Später wenn man Zeit und Geld in dem Projekt hat, kann man dann übere bessere Portierungen nachdenken
-
JoeF schrieb:
Schön das es auch hier immer Neu-mal-kluge Leute gibt.
Das nimmst du sofort zurück
JoeF schrieb:
Ich habe ja nicht behauptet, dass es so gut ist.
Dann sind wir ja einer Meinung.
JoeF schrieb:
Also nochmal: Wenn Autoren ein Buch schreiben, schreiben sie es oftmals für die breite Masse (also auch für Anfänger)
Hmmm. In Büchern für "die breite Masse" steht auch manchmal der grösste Scheiss. Da findet man dann Bücher wo z.B. "void main" drinsteht oder (bei C++) #include<iostream.h> oder es wird ohne "std::" und ohne "using namespace std;" direkt string verwendet.
Es gibt natürlich auch andere, bessere Bücher die diese Fehler nicht enthalten wo der Autor aber trotzdem z.B. malloc() grundlos castet. Ganz einfach daher, weil er es selber nicht besser wusste.
JoeF schrieb:
und da C und C++ eng miteinander verwandt sind
Sie entstammen der gleichen Quelle und teilen Syntax und Semantik. Aber das trifft auch auf die Verwandschaftsbeziehung zwischen C und Objective-C, Pike oder Cilk zu.
Man kann zwar noch C Quellcode mit einem C++ Compiler kompilieren, aber damit hat es sich auch schon.
JoeF schrieb:
wollen sie (denke ich zumindestens) speziell den Anfänger nicht durcheinander bringen.
Gerade Anfänger sollte man darauf hinweisen, dass ein malloc()-cast nicht notwendig ist. Und die wenigen Spezialfälle, wo man malloc() doch mal casten muss, sind für Anfänger erst einmal uninteressant.
JoeF schrieb:
Und du wirst mir wohl recht geben, dass die meisten nicht einen reinen C- Compiler benutzen (ich weiß du ja).
Stimmt. Wenn ich gcc benutze (nicht verwechseln mit g++), verwende ich einen reinen C Compiler.
Und um C++ Quellcode ging es ja nicht. Desweiteren verwendet man in C++ Programmen nicht malloc()/free() sondern new/delete und muss deswegen auch nicht casten
Und wenn doch, dann verwendet man dynamic_cast<T>(var), static_cast<T>(var) oder reinterpret_cast<T>(var).
JoeF schrieb:
Um nun also Fehler vorzubeugen, mußt man malloc casten.
...nur, wenn man innerhalb C++ ist. Dann musst du malloc() casten. Aber wir sind hier im ANSI C Forum, weswegen ich ausschliesse dass der Fragesteller C++ verwendet.
JoeF schrieb:
Nohmal es sollte ja gar kein Aufruf werden, ab sofort nur noch C++ Compiler zu benutzen, um ein C-Quellcode zu kompilieren, sondern nur der Versuch einer Erklärung warum so oft die Diskussion aufkommt wegen dem malloc() und casten oder nicht.
...also nicht casten, ausser man programmiert innerhalb eines C++ Programmes mit C.