[linux-l] Debian-Mirror der belug...

Steffen Dettmer steffen at dett.de
Mi Okt 8 01:57:06 CEST 2003


* Oliver Bandel wrote on Tue, Oct 07, 2003 at 15:32 +0200:
> On Tue, Oct 07, 2003 at 09:19:18AM +0200, Steffen Dettmer wrote:
 [...] 
> > mmm... Hier der Prototyp:
> > 
> > /* Find the run-time address in the shared object HANDLE refers to
> >    of the symbol called NAME.  */
> > extern void *dlsym (void *__restrict __handle,
> >             __const char *__restrict __name) __THROW;
> 
> 
> ich weiß zwar nicht, in welchem Unterholz du das gefunden hast,

in /usr/include/dlfcn.h.

> aber in meiner dlopen() und dlsym() manpages teht da was anderes:
> 
> void* dlopen( const char* filename, int flag );
> void* dlsym ( void* handle, char* symbol );

ähm... Was ist da eigentlich anders? void* bleibt void* :-)

> Wobei dlopen() das handle zurück liefert, das bei dlsym()
> gevbraucht wird.
> 
> dlsym weit man dann dem entsprechenden Funktionspointer zu,
> der auf eine Funktion verweiset, die man sinnvollerweise
> NICHT void* rückgeben lässt, wenn es die gesuchte Funktion
> nicht auch zurückliefert.
> Selbstverständlich deklariert man den benutzten Pointer so,
> wie es in der Lib auch deklariert ist...

Versteh nicht, was Du meinst... Die Funktion gibt ja einen void*
zurück. Klar kannste den casten, aber auch falsch. Genau das
Problem meintest Du doch in Deiner letzen Mail?

.....

struct hallo;
typedef void (*funktion_t1)(int);
typedef struct hallo* (*funktion_t2)(int, struct hallo *, char, int);

funktion_t1 f1 = dlsym(h, "func");
funktion_t2 f2 = dlsym(h, "func");

sollte beides korrekt und ohne Warnungen kompilieren (maximal
muß man den cast noch expliziet hinschreiben, glaub ich).

Welche der beiden Funktionspointer f1, f2 beim Aufruf Mist
machen, merkt man frühestens zur Laufzeit... Ist wirklich blöd
und fehlerträchtig, wie Du ja auch schon schriebst. Seh ich
genauso.

> ...es sei denn man liebt void* über alles, oder schaut
> zu oft aus dem Fenster (besonders dann, wenn der Compiler
> Warnings raus schreibt (ach so, die sind dann eh nicht
> aktiviert...weil da viel zu viel zu lesen ist, was man ja
> garnicht braucht...<räusper>)).

... oder -Wall "vergessen" hat :-)

> > Da kommt man um's void bei der Anwendung nicht so wirklich
> > rum... ;)
> 
> Ja, kommt aber auch drauf an, WO man sie einsetzt,
> und wie man das handhabt.
> An manchen Stelln braucht man die; aber wenn man sie immer und
> überall einsetzt, DANN hat man da ein Problem eingebaut (auch,
> wenn es anfangs sehr bequem ist, weil alles "so problemlos"
> zuweisbar ist...

Aber auf jeden - seh ich ganz genauso! Und wenn man viel castet,
merkt man auch nicht, wenn man falsch castet. Richtig cool wird
das, wenn sich ein Header ändert, z.B.: von:

struct hallo*
find(struct hallo*, const char *const key, int condition);

und man aufruft:

unsigned char *key = "XYZ";
char condition = SUBSTRING_MATCH;

h = find(h2, (char*)key, (int)SUBSTRING_MATCH );

und sich der Header ändert zu:

struct hallo*
find(struct hallo*, int condition, const char *const key);

gibt es in C nichtmal ne Warnung (glaub ich jedenfalls, nicht
probiert) :-) CooL. 

Man wundert sich jetzt vielleicht, wie man auf solche abstrusen
Ideen wie die casts im Beispiel kommt - ABER sowas gibt's in der
Praxis wirklich! Vielleicht ist condition ein enum in C++, der
als char an ne C Funktion übergeben wird, key wird aus einem
Spezial-Buffertyp rausgelesen (der dann nach (const char *const
key) gecastet werden mußte) oder irgendwas anderes, an das sich
nachher eh keiner mehr erinnert :).

Übrigens castet mein Beispiel auch die zwei const's gleich noch mit
weg - sowas sieht man wirklich öfter mal!!

Ja, Oliver, ich seh hier auch Gefahren, da braucht's Diziplin,
wenn da nachher noch was stabil sein soll...

oki,

Steffen

-- 
Dieses Schreiben wurde maschinell erstellt,
es trägt daher weder Unterschrift noch Siegel.




Mehr Informationen über die Mailingliste linux-l