Email List: Xaustin-group-lX
[All Lists]

Re: Return type of dlsym

To: Wojtek Lerch <yyyyyy@xxxxxxx>
Subject: Re: Return type of dlsym
From: Marc Aurele La France <yyy@xxxxxxxxxxx>
Date: Tue, 16 Apr 2002 10:46:18 -0600 (MDT)
Cc: Matt Seitz <yyyyyy@xxxxxxxxx>, <yyyyyyyyyyyyyy@xxxxxxxxxxxxx>
On Sat, 13 Apr 2002, Wojtek Lerch wrote:

> Marc Aurele La France <yyy@xxxxxxxxxxx> said:

> > Oddly enough, I recently ran into this in my own work.  What I ended up
> > with is instead of

> >     fptr = (int (*)(int))dlsym(handle, "my_function");

> > I did

> >     *(void **)(&fptr) = dlsym(handle, "my_function");

> > ... which is, I'll grant, a little kludgy, but is perfectly legal in
> > ANSI or ISO C terms.

> A little?

> It's only "legal" in the sense that it doesn't require the compiler to issue
> a diagnostic; but it is undefined behaviour in ISO C.  And it's actually less
> portable than the original typecast:

>   * On a platform where function pointers are smaller than data pointers,
> you're clobbering memory outside of the fptr variable.  A cast from void* to
> a function pointer would just work: yes, it would throw away the extra bits
> instead of storing them in some unrelated variable, but if the symbol you
> asked for indeed was a function, those extra bits would have all been
> insignificant anyway.

>  * Even if function pointers are the same size as data pointers, their
> representation could be different.  Imagine a machine that stores function
> pointers as "big endian" (segment, then offset) but data pointers as "little
> endian" (offset, then segment).  A normal typecast would allow the compiler
> to swap the segment and the offset; yours doesn't.

Both objections are irrelevant.  My suggestion was given within the
context of the current specification for dlsym().  Given dlsym() is
currently constrained to return a void *, it has no portable means
returning to its caller any information about a symbol other than its
existence/non-existence.  Thus, any portable dlsym() implementation
requires that all pointers have exactly the same representation.

As has already been said, a resolution of this issue should be
two-pronged.  First, the example for dlsym() should be corrected to comply
with ISO C.  Second, I agree with the proposal for the additional
dl[df]sym() entry points.

The last point I'd like to make is that 1003.1-2001 (or whatever you want
to call it) was never meant to be a superset of ISO C.  Rather, they were
to align with each other, where they intersect.  In that sense, any
additional dl*() entries should be viewed as a possible extension to the
now-approved specification, not as a corrigenda.  So are dl[df]sym() in
scope?

Marc.

+----------------------------------+-----------------------------------+
|  Marc Aurele La France           |  work:   1-780-492-9310           |
|  Computing and Network Services  |  fax:    1-780-492-1729           |
|  352 General Services Building   |  email:  yyy@xxxxxxxxxxx          |
|  University of Alberta           +-----------------------------------+
|  Edmonton, Alberta               |                                   |
|  T6G 2H1                         |     Standard disclaimers apply    |
|  CANADA                          |                                   |
+----------------------------------+-----------------------------------+
XFree86 Core Team member.  ATI driver and X server internals.

<Prev in Thread] Current Thread [Next in Thread>