I have a question about best practices involving pointers in function parameters and whether they should be specified as *const or const *const. I know there are varying opinions on use, or excessive use, of const, but at least some use is a good way to catch accidental mistakes.
Say you have the following function, which is part of the implementation of a queue based on a linked list:
void enqueue(struct queue *q, void *data)
{
struct queue_node *item = malloc(sizeof(*item));
item->data = data;
[add node to linked list, specifics are not relevant here]
}
struct queue_node is defined as
struct queue_node {
struct queue_node *next;
void *data;
};
data is not meant to be modified in this function, so it seems like a good idea for data to be of type void *const so you can't accidentally do something like data = item->data instead of item->data = data.
The next level would be to define data as const void *const which means you also can't change what data points to. However, this leads to a warning about discarding the const qualifier from the pointer. And if I understand correctly, further use of such a pointer is considered undefined behavior. Using a cast (item->data = (void *)data) seems clunky.
What's the best approach here? Is const void *const unnecessarily over-protective? It feels like void *const is sufficient to catch most errors.
item->datahas typevoid *, I think it makes sense the thedataparameter to bevoid *orvoid * consteven though the function does not modify the object pointed to bydata. I would only useconst void * dataorconst void * const dataifitem->datahad typeconst void *.