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 types
It is declared in the pthreads headers as
typedef 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 types
Looks 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... :(
Looks 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 declaration
class with pointer to pthread_t
myclass.cpp
~~~~~~~~~~~
#include "myclass.h"
#include <pthread.h>
class function definitions
myclass.h
~~~~~~~~~
pthread_t forward declaration
class with pointer to pthread_t
myclass.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:
Ofcourse there's an extra new and delete in it, but a thread isn't going to be created that much to matter anyway.
// 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.
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 Wassenberg
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.
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement