mr-edd.co.uk :: horsing around with the C++ programming language

Supressing specific warnings on gcc/g++

[9th August 2008]

The content of this post will probably be old news to some people, but I only found this out a couple of days ago and I think it's useful enough to share here.

I recently embarked on a warnings hunt in one of the libraries we're using at work, where I cranked up the compiler warning levels and any warnings produced are extinguished by fixing the code. One of the warnings g++ spat out was to do with an invalid cast from a pointer-to-object to a pointer-to-function.

typedef double (*func_ptr_t)(double, double); // a function pointer type

// Illegal cast: void* to func_ptr_t
func_ptr_t multiply = reinterpret_cast<func_ptr_t>(dlsym(lib_handle, "multiply"));

assert(multiply(5.0, 6.0) == 30.0);

g++ is entirely correct to produce this diagnostic, but this cast is necessary. POSIX's dlsym function finds a function in a shared library and returns a pointer to it. However, the pointer returned is of type void * and so has to be cast to the desired type of function pointer.

Microsoft's Visual C++ compiler has a #pragma warning preprocessor directive to manipulate and disable specific compiler warnings for cases such as this. This seems to be reasonably common knowledge, but I had never heard of anything similar for gcc.

However, I recently discovered that gcc has a special keyword, __extension__, which when written before a statement using a gcc-specific extension, silences any compiler warning relating to that extension, even when strict compiler flags such as -W -Wall -ansi -pedantic are used.

Since a cast such as the one shown above is supported through a gcc extension, we can suppress the warning generated by doing the following:

#ifdef __GNUC__
__extension__
#endif
func_ptr_t multiply = reinterpret_cast<func_ptr_t>(dlsym(lib_handle, "multiply"));

If you're as anal about compiler warnings as I am, maybe you'll find this useful too!

Comments

David Holm

[18/08/2008 at 13:29:00]

Being a fellow pedantic I found this post highly interesting. Generally I don't like to use compiler-specific extensions as they tend to clutter the code but this was a handy one.

A while back I ran into the same problem and came up with the following solution. It is rather ugly but it's somewhat more portable.

typedef double (*func_ptr_t)(double, double);
typedef union {
    func_ptr_t func;
    void* ptr;
} func_ptr_cast_union;

func_ptr_cast_union multiply_cast;
multiply_cast.ptr = dlsym(lib_handle, "multiply");
multiply_cast.func(4.0, 10.5);
(optional)
(optional)
(required, hint)

Links can be added like [this one -> http://www.mr-edd.co.uk], to my homepage.
Phrases and blocks of code can be enclosed in {{{triple braces}}}.
Any HTML markup will be escaped.