November 11, 2022

Attention, C and C++ programmers are more likely to use what I'm going to talk about.

If you're a C++ programmer, you're probably thinking about shared/unique pointers. But that's not what this is about.

Take the void* type. This type can be pretty much anything, this is "okay" if you wanted to make your code more generic, but there is a much better way to handle that. Look at that code:

import core.stdc.stdlib;
void* myInt = malloc(int.sizeof);
*(cast(int*)myInt) = 500;
writeln(*(cast(int*)myInt));
free(myInt);

This is a code that can be common to happen on C, but you can do it a lot better. You can actually make your casting a bit saving information about its size, you could do it with a struct, but you could also do it with one of the D features: slicing:

import core.stdc.stdlib;
void[] myInt = malloc(int.sizeof)[0..int.sizeof);

Now, you will have information saved on how much info is allocated on your int by doing myInt.length. Which means that any attempt to assign data to the pointed location, this location will be bound checked.

Another thing I strongly recommend is not using malloc. The first reason is that it makes your code harder to read, unsafe, untraceable and longer.
If you just use instead:

void[] myInt = new void[int.sizeof];

Will basically have the same effect of the code before in terms of usage, no import, less to write, traceable code (-profile=gc).

Now, if you need to use that just for the sake of generic data and no heap allocation is really needed, I must recall on your mind the underused union and the underused std.variant (aka Tagged Union). My own way to use union if you don't need the tagged union as you already know how your data flow works, this is a pattern that I shall do it from now on (specially because you won't be casting your data all the way instead of just using cast(Something*)(voidPointerData):

This is an example of my generic audio buffer pool for various audio APIs

union HipAudioBuffer
{
    version(OpenAL)
    {
        import openal;
        ALuint al;
    }
    version(OpenSLES)
    {
        import opensles.slinterface;
        SLIBuffer* sli;
    }
    version(XAudio2)
    {
        import directx.xaudio2;
        XAUDIO2_BUFFER* xaudio;
    }
}

Then, instead of just casting your data from void*, you can just access the "cast" itself as a property.

November 12, 2022

On Friday, 11 November 2022 at 13:05:19 UTC, Hipreme wrote:

>

...

Nice article,thank you.