1

I have created a dynamic array struct Vector whose internals I keep hidden from users. Instead, functions are provided to interact with them, such as

bool Vector_push(struct Vector *vector, const void *value)

To help with the popping of elements, the struct holds a pointer to the function that properly deletes each element. This function is set with the function:

void Vector_set_type_destructor(struct Vector *vector, void (*type_destructor)(void *))

I felt it was a little odd to provide a setter without a getter, so I quickly added the following function.

const void (*Vector_type_destructor(const struct Vector *vector))(void *);

Notice how I added the const keyword, as I wanted the type destructor to only be modifiable through the setter, and not through the returned pointer. However, I received the following warning from clang.

src/Vector.c:184:66: warning: function cannot return qualified void type
      'const void' [-Wqualified-void-return-type]
const void (*Vector_type_destructor(const struct Vector *vector))(void *) {
                                                                 ^
src/Vector.c:185:12: warning: incompatible pointer types returning
      'void (*const)(void *)' from a function with result type
      'const void (*)(void *)' [-Wincompatible-pointer-types]
    return vector->type_destructor;

How do I properly return the pointer void (*type_destructor)(void *) through the function without exposing it to possible modification?

Jared
  • 4,240
  • 4
  • 22
  • 27
  • 1
    I don't get it. How could a user modify the pointer to the destructor function? First scenario: I call the getter and store the result in a local variable x. Later I modify the content of x. Now the local variable points to a different function. But the function pointer stored in the struct Vector still points to the original function. No problem! Second scenario: I call the getter, store the result in x. Then I dereference x and modify the bytes stored at its address. That is, I modify the code of the destructor function. No sane person would do that. - Which scenario are you trying to avoid? – jcsahnwaldt Reinstate Monica Jul 23 '16 at 22:51
  • Your title asks about a function pointer, the code shows a pointer to `const` and somehow your text seems to ask for a `const` pointer. Also how does `void *` come into play? See [ask], your question is quite misty. – too honest for this site Jul 23 '16 at 23:06

1 Answers1

4

Try putting const next to the * instead:

void (*const Vector_type_destructor(const struct Vector *vector))(void *);
Rufflewind
  • 8,545
  • 2
  • 35
  • 55
  • The compiler has fallen silent, so this appears to be the correct answer. Could you explain how this is to be read as returning a const pointer of `void (*p)(void *)`? – Jared Jul 23 '16 at 22:12
  • I suggest reading up on an article that explains how how type declarations in C are to be read. For example, see https://stackoverflow.com/a/5503393 and https://stackoverflow.com/a/89100 . – Rufflewind Jul 23 '16 at 23:07
  • Thanks. I usually have most of them down, but this one's just a tad nasty. – Jared Jul 24 '16 at 22:56