How can a function pointer required to be extern(C)?

H. S. Teoh hsteoh at qfbox.info
Wed Apr 12 20:36:59 UTC 2023


On Wed, Apr 12, 2023 at 08:23:51PM +0000, rempas via Digitalmars-d-learn wrote:
> Sorry if the title doesn't make any sense, let me explain. So, I do have the
> following code that does not compile:
> 
> ```d
> import core.sys.posix.pthread; /* The library */
> 
> struct Thread {
> private:
>   pthread_t thread_id;
> 
> public:
>   this(void* function(void*) func, void* arg = null, scope
> const(pthread_attr_t*) attr = null) {
>     pthread_create(&this.thread_id, attr, func, arg);
>   }
> 
>   @property:
>     pthread_t id() { return this.thread_id; }
> }
> 
> ```
> 
> Yes, I'm trying to "encapsulate" the Pthread (POSIX threads) API.
> Normally, the function pointer that is passed to "pthread_create" must
> be "extern(C)" and this is the complaining that the compile does. So,
> I'm thinking to replace the constructor to this:
> 
> ```d
> this(extern(C) void* function(void*) func, void* arg = null,
>      scope const(pthread_attr_t*) attr = null)
> { pthread_create(&this.thread_id, attr, func, arg); }
> ```
> 
> I just added "extern(C)" before the type. This is how it looks in the
> error message so it must work right? Well... it doesn't. And here I am
> wondering why. Any ideas?

IMO this is a bug either in D's syntax or in the parser.  I'd file an
enhancement request.

In the meantime, you can use alias as a workaround:


-------snip-------
extern(C) void* abc(void*) {return null;}

alias FuncPtr = typeof(&abc);
pragma(msg, typeof(abc));
pragma(msg, typeof(&abc));

//void wrapper(extern(C) void* function(void*) callback) {} // NG
void wrapper(FuncPtr callback) {} // OK

pragma(msg, typeof(wrapper));
-------snip-------


T

-- 
A programming language should be a toolbox for the programmer to draw
upon, not a minefield of dangerous explosives that you have to very
carefully avoid touching in the wrong way.


More information about the Digitalmars-d-learn mailing list