Post by Bodo ThiesenPost by Helmut LeitnerPost by dieter_regenbergWelchen Vorteil bzw. Nachteil hat die Verwendung solcher Funktinen unter C?
Man kann damit Dinge machen, die man ohne nicht (oder nur mit
unverhältnismäßig höherem Aufwand) realisieren könnte?
Post by Helmut LeitnerNachteil in C: Es kann leicht sein, dass man irgendwelche zusätzlichen
Parameter braucht, die in der Parameterliste von f nicht vorgesehen sind.
Da bleibt dann nur der Weg, diese Parameter als globale Variablen zugänglich
zu machen (wobei der Code dann nicht reentrant wird).
Wie? Warum? Schonmal was von void * gehört?
Erspar mir bitte solch pupertäres Geschwafel...mit ein bisschen Glück habe
ich schon mit "void *" gearbeitet als du noch gar nicht geboren warst.
Das glaube ich nicht.
Wir können's ja nachrechnen, wenn du Lust dazu hast.
Zur Lösung der von dir angedeutenden Problemstellung hat man "void *" übrigens
nie gebraucht. In den 80-er Jahren hat man halt auf "char *" gecastet und
das gleiche ein bisschen weniger schön und weniger sicher erreicht.
1. Ist das, was ich damit angedeutet habe, elementäres C, und wenn Du
tatsächlich nicht selber auf diese Idee kommst, kann ich
2. nur davon ausgehen, daß Du entweder erst seit weniger als einem Jahr
in C programmierst (dafür aber schon einige Jahre Erfahrung mit einer
anderen Programmiersprache hast, die einen mit Zeigern konfrontiert),
oder Du insgesamt maximal seit ein paar Jahren überhaupt programmierst.
Ich programmiere seit 1983 in C. 1979 habe ich mein erstes Geld mit einem
Softwareprojekt verdient. Und seit 1988 bin ich als SW-Entwickler selbständig
und mache ca. 1/3 meines Umsatzes in C.
Emprisch gesehen muss also irgendwo in deinen Schlußfolgerungen ein Wurm sein.
Deine dunklen Andeutungen über die Problemlösungkapazität von "void *" im Bezug
auf die Frage des OP kann ich nicht nachvollziehen (bin kein Gedankenleser).
Post by Bodo ThiesenDas war übrigend genau /der/
Fall, in dem ich void * /überhaupt/ akzeptiere... (Siehe irgendeinen Artikel
des letzten Monats von mir...)
Das geht aber nur beschränkt (nämlich wenn du den "Caller" in der Hand hast).
Wenn ich den Caller in der Hand habe, lasse ich mir keinen void *
übergeben, sondern lege die Struktur für den Caller fest.
Nicht wenn das Interface abstrakter sein soll.
An qsort wird die Tabelle mit "void *" übergeben, aber wenn du zum Sortieren
irgendwelche zusätzlichen Hilfsdaten benötigst, dann kannst du die Callback-
Parameterliste für das qsort nicht erweitern.
qsort hat den Nachteil nur Elemente gleicher Größe sortieren zu können.
Das habe ich nicht gesagt und nicht gemeint.
void * hash=malloc(sizeof(void *) * 3);
assert(hash);
hash[0]="Hallo";
hash[1]="du";
hash[2]="da!";
qsort(hash,3,sizeof(void *),compare);
Da werden Elemente unterschiedlicher Größe sortiert. (BTW: Dies ist nur
ein Beispiel.)
Du löst ein triviales (ein sogenanntes Strohmann-) Problem...
Ein beliebter Foren-Diskussions-Trick. Man wirft ein seitwärts vom Thema
liegendes Problem auf, das trivial und elegant gelöst wird (was aber eh
jeder weiß) und versucht dadurch Kompetenz zu gewinnen...
Das ist besonders lästig, weil nicht einmal ein Offset-Parameter vorgesehen
ist. Gäbe es den, dann könnte man wenigstens für typische Sortierungen (z. B.
nach double aufsteigend) mit einer einzigen Callback-Funktion auskommen.
struct sort_struct {
int offset;
void * ptr;
};
(Die erhöhte Laufzeit durch das initialisieren des Arrays fält bei
hinreichend großen Arrays überhaupt nicht mehr auf, und bei kleinen
kann man es andererseits vernachlässigen - außer es passiert in einer
Schleife...)
Es ist klar, dass es Work-Arounds gibt. Darum ging es aber nicht.
Der OP wollte wissen, welche Vor- und Nachteile C-Callbacks haben.
Wer C religiös verteidigen will, kann natürlich sagen, dass C-Callbacks
keine Nachteile haben, dass C keine Schwächen hat, dass C die beste
aller Sprachen ist ...
... und damit habe ich nicht mal ein emotionales Problem, weil C für mich
nach wie vor mein Lieblingssprache ist. Aber ich bin nicht blind verliebt.
So
muss man praktisch für jede Struktur, die man sortieren will, eine eigene
Callback-Funkton schreiben oder den Offset global beisteuern.
Offset global löst das Thread-Save-Problem nicht. Die unterschiedlichen
Callback-Funktionen schon.
Hab ich doch gesagt!? ;-)
Ansonsten könnte ich Dir noch das Inferface
void sortx(
void *arg,
int first,
int last,
int myownuse,
int maxownuse,
int (*compare)(void*,int,int),
void (*swap )(void*,int,int),
void (*average)(void*,int,int,int)
);
Ist sicher ein universelleres Interface als qsort. Es ist nicht das erste
solche alternative Interface das ich sehe und es zeigt, dass qsort eben
seine Schwächen hat. Andererseits sehe auch in deinem Interface Schwächen,
aber API-Design ist ja nicht das Thema.
Herauszufinden, wie Deine allgemeine double-Sort Callback-Funktion aussehen
könnte, das überlasse ich jetzt Dir, dann kannst Du mal - entgegen meiner
Behauptung von weiter oben - beweisen, doch Ahnung von C zu haben.
Das meine ich mit pubertär: das Bedürfnis zu haben, hier was zu beweisen.
Ich habe das Bedürfnis nicht.
Post by Bodo ThiesenIst hier OffTopic. Wenn wir D wollen, gehen wir nach dang und starten
einen RfD für de.comp.lang.d
Ein kleiner Sprachvergleich wird wohl erlaubt sein, oder willst
du als "Scheuklappen-Bodo" in die Geschichte eingehen?
char [][] DirFindFile(char [] dir,char [] fspec, int flags)
{
char [][] files;
DirFindFileCall(dir,fspec,
delegate int (char [] dir, char [] fnam, WIN32_FIND_DATA *b)
{
files ~= (dir ~ fnam);
return 0;
}
,flags
);
return files;
}
Was ist da der Unterschied zu
char * * files;
int delegate (char * dir, char * fnam, WIN32_FIND_DATA *b) {
files ~= (dir ~ fnam); /* Müsste noch sinnvoll angepasst werden...
return 0;
}
char * * DirFindFile(char * dir,char * fspec, int flags) {
DirFindFileCall(dir,fspec,delegate,flags);
return files;
}
Dass es nicht Thread-Save ist. Dass die Logik nicht an einer Stelle
konzentriert ist.
Außer, daß D eine andere Syntax benutzt, und der Callback-Funktion keinen
Namen gibt (und man bei diesem Funktionslayout nicht um eine globale
Variable herum kommt)?
Die Unterschiede sind fein.
Mir ging es darum, dem OP eine Frage zu beantworten.
Dir geht es scheinbar darum, auf einer Disput-Showbühne zu glänzen.
--
Helmut Leitner ***@hls.via.at
Graz, Austria www.hls-software.com