Неполный тип массива?

Когда я скомпилировал следующий код с gcc -Wall -pedantic -ansi -std=c89, он скомпилировался успешно, не указав ошибку при назначении указателя. Обратите внимание, что я конвертирую из int (*)[4] в int (*)[].

int arr[4];
int (*p_arr)[] = &arr;

Предполагая, что есть какая-то причина для разрешения этого (несовместимого?) назначения, когда я пытаюсь его использовать, компилятор дает ошибку неполного типа error: invalid application of ‘sizeof’ to incomplete type ‘int[]’.

(void) sizeof(*p_arr);

Эта ошибка заставляет меня подумать, что использовать разрешение предыдущего назначения указателя p_arr = &arr? Разрешено ли это присвоение стандарту?

Я использовал неполный тип struct/union (обычно для прямого объявления), а также обнаружил ошибку incomplete array element type. Но это incomplete array type для меня нова. Возможно ли это в стандарте C и имеет прецедент?

Ответ 1

Это присваивание не выдавало ошибок, поскольку их типы совместимы, поскольку массивы неизвестной привязки совместимы с любым массивом типа совместимого элемента. (Для справки) -

int (*p_arr)[] = &arr;

Но дает ошибку при передаче в качестве операнда оператора sizeof, потому что *p_arr имеет неполный тип, и вы не должны использовать неполные типы в качестве операндов для оператора sizeof.

N1570 6.5.3.4

1 Оператор sizeof не должен применяться к выражению, которое имеет тип функции или неполный тип, в имя в скобках имени такого типа или выражение, которое обозначает член битового поля [...].

Теперь, что вы можете использовать, вот простой пример -

#include <stdio.h>

int main(void){
    int arr[4]={1,2,3,4};
    int a[6]={1,2,3,3,1,1}; 
    int (*p_arr)[] = &arr;
    for(int i=0;i<4;i++)
       printf("%d",(*p_arr)[i]);
    printf("\n");
    p_arr=&a;
    for(int i=0;i<6;i++)
       printf("%d",(*p_arr)[i]);
    return 0;
}