DRAFT document on coding conventions in kde libraries

Frerich Raabe raabe at froglogic.com
Mon Mar 6 16:04:04 GMT 2006


On Monday 06 March 2006 16:02, Friedrich W. H. Kossebau wrote:
> Am Montag, 6. März 2006 15:37, schrieb Frerich Raabe:
> > On Monday 06 March 2006 15:12, André Wöbbeking wrote:
> > > On Monday 06 March 2006 14:57, Frerich Raabe wrote:
> > > > On Monday 06 March 2006 14:33, Frans Englich wrote:
> > > > > Could you give an example of when one would have to use a C-style
> > > > > cast?
> > > >
> > > > When casting the pointer returned by dlsym to the correct type, for
> > > > example.
> > >
> > > reinterpret_cast<>() doesn't work in this case?
> >
> > No.
>
> Hm. Please teach here why :)
> dlsym returns "void *"? And that could not be "reinterpreted" to the
> supposed type?

That is right. void* can be a data pointer or a function pointer. You can just 
google for 'c style cast dlsym' for many hits about this issue - and I think 
I even saw some open-std entry for this at some point. Here's an interesting 
quote for you:

 It's not in the list of permitted conversions, 
 so it isn't permitted. In the C standard, for example, we have 
 (ISO 9899:1999, §6.3.2.3/7): "A pointer to an object or 
 incomplete type may be converted to a pointer to a different 
 object or incomplete type." for data pointers, and (§6.3.2.3/8) 
 "A pointer to a function of one type may be converted to a 
 pointer to a function of another type and back again; the result 
 shall compare equal to the original pointer." for pointers to 
 functions, but nothing for going from one to the other. In C++, 
 it's a bit more complicated: you have to look at all of the 
 permitted conversions for static_cast and reinterpret_cast, but 
 you won't find any that allow going between a pointer to data 
 and a pointer to a function either. 
 
 It's also worth reading what Posix has to say about it in the 
 rationale for dlsym(): 
 
 The ISO C standard does not require that pointers to 
 functions can be cast back and forth to pointers to data. 
 Indeed, the ISO C standard does not require that an object 
 of type void * can hold a pointer to a function. 
 Implementations supporting the XSI extension, however, do 
 require that an object of type void * can hold a pointer to 
 a function. The result of converting a pointer to a function 
 into a pointer to another data type (except void *) is still 
 undefined, however. Note that compilers conforming to the 
 ISO C standard are required to generate a warning if a 
 conversion from a void * pointer to a function pointer is 
 attempted as in: 
 
 fptr = (int (*)(int))dlsym(handle, "my_function"); 
 
 Due to the problem noted here, a future version may either 
 add a new function to return function pointers, or the 
 current interface may be deprecated in favor of two new 
 functions: one that returns data pointers and the other that 
 returns function pointers. 
 
 Finally, g++ does NOT allow it with either a reinterpret_cast 
 nor a static_cast -- presumably because the C++ does not allow 
 it. Of course, in C++, a C style cast MUST resolve into a 
 reinterpret_cast or a static_cast, followed (or preceded, I 
 forget) by a const_cast. Why this wierd solution, I don't know. 
 (Sun CC gives a warning for both the C style cast and the 
 reinterpret_cast.) Perhaps the people responsible for the C 
 compatible parts have a different opinion vis-a-vis standards 
 conformance than those responsible for the C++ parts. 
 
 It worked before, so g++ can't just remove it, regardless of 
 what the standard says. This may also be the justification for 
 not supporting it in reinterpret_cast -- there was no 
 reinterpret_cast "before". IMHO, the correct solution would be 
 a warning (which can be turned off), converting to an error when 
 I specify -std=c++98; the fact that it isn't an error when I 
 specify -std=c++98 can only be considered an error in the 
 compiler (or else -std=c++98 doesn't mean what I think it should 
 mean). 

> Would it be an idea then to mark such needed C-style cast with a makro, to
> make it distinct from wrong use? E.g.
>   SupposedType var = kmodule_cast(SupposedType)( SomeSymbol );
> given
>   #define kmodule_cast(x) (x)
> perhaps?

Maybe this is nice, I'm undecide. The true fix is not to just read a bunch of 
books and think that all the information your consumed saves you from 
actually using your brain.

The difficult part about all those fancy C++ casts and C++ patterns and 
whatnot is to decide when you should *not* apply them.

-- 
Frerich Raabe - raabe at froglogic.com
www.froglogic.com - Qt consulting and add-ons




More information about the kde-core-devel mailing list