tsearch und strcasecmp

05/09/2008 - 10:10 von Daniel Leidert | Report spam
x-post de.comp.os.unix.programming + de.comp.lang.c, fup auf erstere
gesetzt

Hallo,

In einem kleinen C-Programm für Linux/Unix wird tsearch so aufgerufen:

| tsearch(newstring(id), &idtree, strcasecmp);

(interessant ist nur das 3. Argument). Daraufhin beschwert sich der GCC
mit:

| passing argument 3 of ‘tsearch’ from incompatible pointer type

Eine Möglichkeit wàre, eine Wrapper-Funktion zu schreiben:

| int mycompare (const void *s1, const void *s2) {
| return strcasecmp ((const char *) s1, (const char *) s2);
| }
| ...
| (void) tsearch(newstring(id), &idtree, mycompare);
| ...

Der Autor des Programmes ist damit aber nicht glücklich. Zusammenfassend
sind ihm 2 Funktionsaufrufe zu "verschwenderisch" und er hàtte erwartet,
dass der Compiler ein (char *) akzeptiert, wo ein (void *) erwartet wird.
Er hat das Problem jetzt so gelöst, dass er einen Typecast beim Aufruf
von tsearch macht:

| typedef int(*compar_fn_t)(const void *, const void *);
| ...
| tsearch(newstring(id), &idtree, (compar_fn_t)strcasecmp);

Meine Frage ist jetzt: Ist eine der beiden Varianten der anderen
vorzuziehen und wenn ja, warum? Oder ist eine dritte Variante die
"richtige"?

Falls sich hier GCC-Kenner rumtreiben, steht da noch die Frage im Raum, ob
der GCC intelligent genug ist, in Lösung 1 den 2. Funktionsaufruf
"wegzuoptimieren"?

MfG Daniel
http://www.wgdd.de & http://debian.wgdd.de
Usenet-FAQ http://www.afaik.de/usenet/faq/ & http://got.to/quote
de.sci.chemie http://www.dsc-faq.de & http://www.chemie-webverzeichnis.de
de.comp.security.*-FAQs http://www.linkblock.de
 

Lesen sie die antworten

#1 Markus Wichmann
05/09/2008 - 11:03 | Warnen spam
Daniel Leidert schrieb:
Hallo,




Hallo.

In einem kleinen C-Programm für Linux/Unix wird tsearch so aufgerufen:

| tsearch(newstring(id), &idtree, strcasecmp);

(interessant ist nur das 3. Argument). Daraufhin beschwert sich der GCC
mit:

| passing argument 3 of ‘tsearch’ from incompatible pointer type

Eine Möglichkeit wàre, eine Wrapper-Funktion zu schreiben:

| int mycompare (const void *s1, const void *s2) {
| return strcasecmp ((const char *) s1, (const char *) s2);
| }
| ...
| (void) tsearch(newstring(id), &idtree, mycompare);
| ...

Der Autor des Programmes ist damit aber nicht glücklich. Zusammenfassend
sind ihm 2 Funktionsaufrufe zu "verschwenderisch" und er hàtte erwartet,
dass der Compiler ein (char *) akzeptiert, wo ein (void *) erwartet wird.
Er hat das Problem jetzt so gelöst, dass er einen Typecast beim Aufruf
von tsearch macht:

| typedef int(*compar_fn_t)(const void *, const void *);
| ...
| tsearch(newstring(id), &idtree, (compar_fn_t)strcasecmp);

Meine Frage ist jetzt: Ist eine der beiden Varianten der anderen
vorzuziehen und wenn ja, warum? Oder ist eine dritte Variante die
"richtige"?




Wie immer führen viele Wege nach Rom. Welchen man genommen hat, ist
doch egal, solange man angekommen ist, oder? Ich meine, die zweite
Lösung liegt eigentlich eher auf der Hand: Der Typ stimmt nicht, also
muss man casten. Letztlich macht die erste Lösung das doch auch, nur
an anderer Stelle. Ich hàtte wahrscheinlich auch die erste Lösung
genommen. Natürlich klappt das nur dann, wenn man weiß, dass ein
void-Pointer genauso aussieht, wie ein char-Pointer. Ich weiß nicht,
ob das irgendwo garantiert ist.

Falls sich hier GCC-Kenner rumtreiben, steht da noch die Frage im Raum, ob
der GCC intelligent genug ist, in Lösung 1 den 2. Funktionsaufruf
"wegzuoptimieren"?




Mache aus der Funktion ein Makro, dann bestimmt. Ansonsten mal auf -O3
hoffen. Das schafft einiges (es entfernt sogar Schleifen, die unnötig
sind).

MfG Daniel



HTH,
Markus
Nur weil ein Genie nix reißt, muß ja nun nicht gleich jeder Idiot
pausieren... Bully hats ja auch geschafft.

Ähnliche fragen