-1

My question is related to this one but I did not find an answer there. The reason you may want to use void** is just to avoid an excess of typecasting or is there another one? I ask this because I guess you can always use a void* as a void** but I could be missing something else. Just to test if it was like this, I wrote these lines:

#include "stdio.h"
#include "stdlib.h"

void **a;
void *b;

int MyFunction(int a)
{
    return 1;
}

int MyFunction_2(int a)
{
    return 2;
}

typedef int (function_pointer)(int);

void main(void)
{
    b = malloc(2 * sizeof(void*));
    *((void**) b) = MyFunction;
    *((void**) b + 1)  = MyFunction_2;
    a = (void**) malloc(2 * sizeof(void*));
    *a = MyFunction;
    *(a + 1) = MyFunction_2;

    printf("Result = %d\n", ((function_pointer *) *((void**) b))(1));
    printf("Result = %d\n", ((function_pointer *) *((void**) b + 1))(1));
    printf("Result = %d\n", ((function_pointer *) *a)(1));
    printf("Result = %d\n", ((function_pointer *) *(a + 1))(1));
}

It compiles without any warning and the output is (as I expected):

Result = 1
Result = 2
Result = 1
Result = 2

Edit

I feel like you misunderstood the question. It is not about the code I am showing, I do not care how wrong it is and I do not think it is fine in any aspect, I would never use something like that (it was hard to make it work, actually). My doubt was related to why or in what conditions void** could or should be used since in every example I can think of, I could just use a void*. The only reason I can think about is avoiding typecasting. Is there anything else?

  • 3
    It compiles with a lot of warnings: https://godbolt.org/z/HQFV9s – UnholySheep Nov 30 '19 at 21:48
  • 1
    *"t compiles without any warning"* - that depends on the naivety level to which you've chosen to configure your toolchain. Sufficient paranoia will generate *plenty* of warnings. – WhozCraig Nov 30 '19 at 21:51
  • 2
    You should use `%p` to print a pointer. – stark Nov 30 '19 at 21:57
  • 2
    If you're trying to use `void **` as a "generic pointer to pointer" type, that's not portable in C. There *is no* generic pointer-to-pointer type in C. See also [question 4.9](http://c-faq.com/ptrs/genericpp.html) in the old [C FAQ list](http://c-faq.com/). – Steve Summit Nov 30 '19 at 21:59
  • 4
    `void **` is not a pointer to an unknown type -- it's a pointer to a `void *`, which is different from `void`. You use it when you need a pointer to a `void *` object, eg. to modify its value. – Dmitri Nov 30 '19 at 22:00
  • Sorry, @UnholySheep, my bad. – rocomanmelli Nov 30 '19 at 22:08
  • You are right, @WhozCraig. – rocomanmelli Nov 30 '19 at 22:09
  • I am not printing pointers but integers, @stark. – rocomanmelli Nov 30 '19 at 22:11
  • If there is no warning you are using a non-conforming compiler (the code contains a constraint violation which requires a diagnostic) – M.M Dec 01 '19 at 01:00
  • 1
    @rocomanmelli printing with the wrong format specifier [invokes undefined behavior](https://stackoverflow.com/q/16864552/995714). For example when pointers are 64-bit long but int contains only 32 bits then you've already messed up the stack on many platforms. `%p` prints the pointer in integer form, or if you really want to use an integer type then you must cast to `(u)intptr_t` which are the only types that are guaranteed to be "compatible" with pointers. In that case use [`printf("%" PRIuPTR "\n", (uintptr_t)pointer)`](https://stackoverflow.com/q/5795978/995714) – phuclv Dec 01 '19 at 01:16
  • `*a`, `*(a +1)` better written a `a[0]`, `a[1]`. – Antti Haapala -- Слава Україні Dec 01 '19 at 03:49
  • I did not want to print pointers but the integers returned by the functions whose addresses are in those pointers, @phuclv. – rocomanmelli Dec 01 '19 at 05:08

1 Answers1

2

Why to use void**?

you can always use a void* as a void** but I could be missing something else

Code attempts to save a function pointer as a void *, which is undefined behavior. Conversion to/from void * with an object pointer is defined.

There is no clear reason to use void ** here.

Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256