Согласно C99 §6.2.5p27 и C11 §6.2.5p28:
Все указатели на типы структуры должны иметь одинаковое представление и согласования друг с другом.
С примечанием (#39 и #48 соответственно):
Те же требования к представлению и выравниванию подразумевают взаимозаменяемость в качестве аргументов функций, возвращаемые значения из функций и членов профсоюзов.
(Обратите внимание, что C89 §3.1.2.5 не указывает о указателях на структуры)
-
Известно, что указатель на void, например, C11 §6.3.2.3p1:
A pointer to void may be converted to or from a pointer to any object type.
Не означает, что указатель на указатель на void совпадает с указателем на void и не подразумевает то же, что и другие указатели на указатели на объекты данных.
(Я прошу прощения, если я использую термин "подразумеваю одно и то же" слишком свободно, он предназначен для использования только в указанном контексте)
Ниже приведен пример кода, демонстрирующий общий указатель на указатель на struct:
#include <stdio.h>
#include <stdlib.h>
int allocate_struct(void *p, size_t s) {
    struct generic { char placeholder; };    
    if ( ( *(struct generic **) p = malloc(s) ) == NULL ) {
        fprintf(stderr, "Error: malloc();");
        return -1;
    }
    printf("p:  %p;\n", (void *) *(struct generic **) p);
    return 0;
}
int main(void) {
    struct s1 { unsigned int i;  } *s1;
    if (allocate_struct(&s1, sizeof *s1) != 0)
        return -1;
    printf("s1: %p;\n\n", (void *) s1);
    s1->i = 1;
    free(s1);
    return 0;
}
GCC:
-std=c89 -pedantic-errors -Wall -Wextra -fstrict-aliasing -Wstrict-aliasing=3 -O3
Результат: (без предупреждений)
p:  0x800103a8;
s1: 0x800103a8;
.
Вопрос
Является ли подразумеваемая взаимозаменяемость указателей на структуры применимы также к указателям на указатели структур?
Просто пояснить: вопрос о struct x ** vs other struct y **, а не о struct x * vs struct y **.