   How to forward declare pthread_t when that is a typedef
  I'm using pthreads for win32 and I want to forward declare pthread_t:struct pthread_t;but I get this error:'pthread_t' : redefinition; different basic typesIt is declared in the pthreads headers astypedef struct {    void * p;    /* Pointer to actual object */    unsigned int x;   /* Extra information - reuse count etc */} ptw32_handle_t;typedef ptw32_handle_t pthread_t;where ptw32_handle_t is a struct; however on a Linux system, pthread_t is itself a struct, not typedef, and I want my code to build on Win and Linux.So how do I do the forward declaration?  I don't want to include pthread.h in the header with the class declaration where I'm storing a *pthread_t as it's a file that gets included in many places where pthread.h doesn't need to be.[Edited by - Prune on April 29, 2009 7:11:24 PM]
#ifdef _WIN32  struct ptw32_handle_t;  typedef ptw32_handle_t pthread_t;#else  struct pthread_t;#endif;  error C2371: 'ptw32_handle_t' : redefinition; different basic typesLooks like ptw32_handle_t is a typedef as well (typedef struct {...} ptw32_handle_t).  Since the struct ptw32_handle_t is a typedef of is unnamed, I can't forward declare that one... :(   ;  If you're getting redefinition errors then it's obviously already defined for you, so why do you need to forward declare it?   ;  The error is in pthread.h which is included in the .cpp file.myclass.h~~~~~~~~~pthread_t forward declarationclass with pointer to pthread_tmyclass.cpp~~~~~~~~~~~#include "myclass.h"#include <pthread.h>class function definitions   ;  When I want to achieve something like that (for example when an exported class contains non-exported template-instantiated members), I use something I stole from Qt:// Header fileclass foo : public boost::noncopyable{    // Forward declaration of my implementation class    class impl;    // If you don't want to create your own copy constructor and assignment operator, use a shared ptr from the standard library or boost, or inherit from boost::noncopyable    impl *d;    foo();    ~foo();}// Implementation fileclass foo::impl{public:    pthread_t *handle;};foo::foo()    : d( new impl() ){}foo::~foo(){   delete d;}Ofcourse there's an extra new and delete in it, but a thread isn't going to be created that much to matter anyway.   ;  The issue is that the mutexes they have are also typedefs, and there the additional pointer indirection will have a performance impact.I'm tempted to use, if I can't resolve this issue, the operating system API, with user-space interlocked operations to check when locks don't need to call WaitForSingleObject etc.It's simple enough on Windows, but I also need it to build on Linux and there I'm not sure what threading API is provided by the OS, to bypass pthreads.   ;  How about creating a new struct pthread_t_wrapper, which would be forward-declared in your interface and defined in your implementation to hold a pthread_t? There's no runtime cost, but you'd have to change all pthread API call sites to use the wrapper's member.   ;Quote:Original post by Jan WassenbergHow about creating a new struct pthread_t_wrapper, which would be forward-declared in your interface and defined in your implementation to hold a pthread_t? There's no runtime cost, but you'd have to change all pthread API call sites to use the wrapper's member.Or you could re-implement the interface in the wrapper by delegation. That should get optimized out too, in normal circumstances anyway.   ;  Just include pthread.h in myclass.h. The days of obsessively minimizing header inclusions to speed up compilation are pretty much over... our hard disks are a lot faster these days. Obsessively minimizing header inclusions to prevent circular inclusion thanks to C/C++'s quaintly broken linker model, of course, is still de rigueur. But that doesn't apply to API includes.   