1

I'm newbie in the ansi and iso world, i compiled my program with :

-asni -pedantic -std=c++11 -std=c++98 

Now, i get the following warning:

 warning: converting from 'void (NetworkSocket::*)()' to 'void* (*)(void*)' [-pedantic]

for the following line:

if (pthread_create(this->threadArray, NULL, (void*(*)(void*)) &NetworkSocket::threadProcedure  , (void *)this) != 0)
        { /* error */      }

How can i pass pedantic warning?

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • 3
    First, drop two of the three: `-ansi -std=c++11 -std=c++98` because `-ansi` and `-std=c++98` are the same, and `std=c++11` conflicts with the other two. – rubenvb Jul 28 '12 at 14:19
  • How about making NetworkSocket::threadProcedure static? – Vaughn Cato Jul 28 '12 at 14:25
  • Good point, it's just a thread procedure. If for some reason you need instance member access in there and can't use the extra data parameter, `std::bind` is your best option. If not, go for the static function. – chris Jul 28 '12 at 14:29
  • 2
    [A function pointer cast is a bug waiting to happen](http://blogs.msdn.com/b/oldnewthing/archive/2011/05/06/10161590.aspx). "There, that shut up the compiler. Those compiler guys are so stupid. They can't even figure out how to convert one function pointer to another. I bet they need help wiping their butts when they go to the bathroom." – Adam Rosenfield Jul 28 '12 at 14:42
  • @chris, how do you pass a bind expression to `pthread_create`? – Jonathan Wakely Jul 28 '12 at 15:06
  • @JonathanWakely, Good point. I forgot it can't take those. Guess if you need more than one piece of extra data, a pointer to a struct containing both? – chris Jul 28 '12 at 15:08
  • possible duplicate of [pthread Function from a Class](http://stackoverflow.com/questions/1151582/pthread-function-from-a-class) – Jonathan Wakely Jul 28 '12 at 15:09

1 Answers1

3

pthread_create is a C function expecting a C function taking a void pointer, and returning a void pointer. So you can use such a C function to dispatch the call to you member function, if you use the this pointer as thread argument:

extern "C" void* startThread( void* p )
{
    static_cast< NetworkSocket* >( p )->threadProcedure();

    return 0;
} 

if ( pthread_create( this->threadArray, 0, startThread, this ) )
   ...
Torsten Robitzki
  • 3,041
  • 1
  • 21
  • 35
  • Using C-linkage (the `extern "C"` part) is unnecessary. Additionally it is possible to use a function inside the class, if it's a static function (with `void* (*fn)(void*)` as its signature). – Giel Jul 28 '12 at 17:57
  • 2
    @Giel: while a function without `extern "C"` linkage will work in almost all cases, strictly speaking it *is* necessary (C++ and C language ABIs need not be the same for free functions, though they nearly always are - similarly for static member functions). Even if you don't care for the language lawyer rationale, since there's no harm in having the `extern "C"` and it describes exactly what is intended, it should be used. Especially if you're interested in `-pedantic` warnings... – Michael Burr Jul 28 '12 at 20:46
  • 1
    @Giel: That is a common misconception. You can **not** use static member functions. Unfortunately a lot of people do and it `seems` to work. The problem is that The pthread library is a C library and does not understand anything about C++ so it can technically only call C functions. Calling C++ functions is non portable and they are just getting lucky `on that particular compiler` that the same calling convention is used for C function as for a C++ static member function. There is no requirement in the standard that this is true (and I know several platforms where it is not). – Martin York Jul 31 '12 at 14:31