willemt / raft

C implementation of the Raft Consensus protocol, BSD licensed
Other
1.12k stars 268 forks source link

why use raft_server_t* in all functions? instead just use raft_server_t #5

Open dimitar9 opened 9 years ago

dimitar9 commented 9 years ago

Hi Willemt, I like your work so much. I have a question here:

void raft_set_current_term(raft_servert* me, int term) { raft_server_privatet* me = (void*)me; me->current_term = term; }

Like this, why not just use raft_server_t, since it is already void*. I don't quite understand. Could you please tell me?

Thank you

willemt commented 9 years ago

Hey that's a good question

The one and only reason why raft_server_t is void* is because of encapsulation.

A void* typedef means I can do whatever with my implementation and keep the details private.

There's no other reason for me using the void* typedef

Why do I use raft_server_t* instead of raft_server_t, which is a void* pointer already? I don't like creating types that are pointers by default. It makes the code harder to understand. If you have pointer-less types then the person reading the code never needs to ask "is this type a pointer?". Seeing the explicit * makes the source more readable.

Why don't I use just void* in every function prototype? The compiler does some handy type checking for you even if the typedef is a void_. For example, if someone passes a raft_peert into a function that expects a raft_server_t* it will complain. This is a win.

So if I'm effectively using void* * for all my raft_server_t* references why does it work? This works because the void* is the same as void. It's just a pointer. They're equivalent in this case.

Hope this makes sense.

In the last month I've found a better technique for encapsulation. If you're interested you might want to look at the heap_t typedef in https://github.com/willemt/heap/blob/master/heap.h