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.
|