avoid extra variable during void pointer cast

Marco Leise via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun May 14 14:07:36 PDT 2017


Am Sun, 14 May 2017 20:18:24 +0000
schrieb Kevin Brogan <kevin at brogan.ca>:

> I have a piece of code that takes a callback function.
> 
> The callback has the signature void callback(void* state, void* 
> data)
> 
> There are several of these functions. All of them use state and 
> data as differing types.
> 
> As an example, let's look at one that uses both of them as int*.
> 
> addInt(void* state, void* data)
> {
>      *cast(int*)state += *cast(int*)data;
> }
> 
> Is it not possible to specify the cast as an alias so that I can 
> declare the cast once at the beginning of the function?
> 
> Something like this?
> 
> addInt(void* state, void* data)
> {
>      alias _state = cast(int*)state; // Error: basic type 
> expected, not cast
>      alias _data = cast(int*)data; // Error: basic type expected, 
> not cast
> 
>      *_state += *_data;
> }

No, that is not possible. An alias can only be assigned a
symbol.

> I can always do this:
> 
> addInt(void* state, void* data)
> {
>      int* _state = cast(int*)state;
>      int* _data = cast(int*)data;
> 
>      *_state += *_data;
> }
> 
> But I don't want to create a new variable and assign it everytime 
> I call the function. The examples I'm using are contrived, but in 
> the c code I am porting this from, the callback gets called 
> thousands of times a second, every optimization matters, and the 
> variables are used many times per function. I don't want to 
> riddle the code with casts if i can avoid it and I don't want to 
> create and destroy useless proxy variables every time the 
> function is called.

Let the compiler optimize the assignment away and don't worry
much about it. Inlining also works well within the same module.
In this case here I would probably use "consume" functions as
I dub them:

	import std.traits;
	pragma(inline, true) /* Not really needed I hope ;) */
	ref T consume(T)(ref void* data) if (!hasIndirections!T)
	{
		T* ptr = cast(T*)data;
		data += T.sizeof;
		return *ptr;
	}

You can then rewrite your addInt function like this:

	void add(T)(void* state, void* data) if (isNumeric!T)
	{
		state.consume!T += data.consume!T;
	}

-- 
Marco



More information about the Digitalmars-d-learn mailing list