Puede int (*)[]
ser un tipo incompleto?
C 2018 6.2.5 1 dice:
En varios puntos dentro de una unidad de traducción, un tipo de objeto puede estar incompleto (sin información suficiente para determinar el tamaño de los objetos de ese tipo) o completo (con información suficiente).
Por lo tanto, parece que si se conoce el tamaño de un tipo, el tipo está completo. 6.2.6.1 28 especifica que ciertos tipos de punteros deben tener los mismos tamaños (punteros a void
y caracteres, punteros a tipos compatibles, punteros a estructuras y punteros a uniones), pero los punteros a otros tipos pueden variar.
En una implementación en C donde todos los punteros, o todos los punteros a las matrices int
, tienen el mismo tamaño, entonces int (*)[]
se conoce el tamaño de , por lo que estaría completo. En una implementación que, por ejemplo, utiliza diferentes punteros para matrices grandes, el tamaño no se conocería, por lo que está incompleto.
Como MM señala , una estructura no debe contener un miembro con un tipo incompleto, excepto un miembro de matriz flexible final, según una restricción en 6.7.2.1 3. Esto sugiere que una implementación con un tamaño de punteros debe aceptar struct { int (*p)[]; }
mientras que una implementación que tiene diferente los tamaños para tales matrices deben diagnosticar una violación de restricción. (Esto a su vez significa que dicha declaración no es parte de la estricta conformidad C.)
fuente
void *
esté completo muestra que se puede completar un puntero a un tipo incompleto. No muestra si un puntero a un tipo incompleto puede estar incompleto. Si uno pregunta "¿Puede un mamífero ser un elefante?", Mostrar que "Un león es un mamífero" no proporcionaría que un mamífero no puede ser un elefante. La pregunta pregunta si el conjunto X de punteros a tipo incompleto puede contener un elemento que está incompleto. Mostrar que el conjunto X de punteros a tipo incompleto contiene un elemento que está completo es irrelevante.Respuestas:
Una matriz de tamaño desconocido está incompleta:
Sin
int (*)[]
embargo, el tipo no está incompleto: es un puntero de una matriz deint
tamaño desconocido.Y un puntero tiene un tamaño bien conocido:
Además, incluso puede desreferenciarlo, gracias a la semántica de la matriz:
Editar
Además, un puntero es siempre un tipo completo. Está escrito en negro sobre blanco en 6.2.5 / 20:
fuente
printf
solo muestra que un puntero a una matriz incompleta está completo en la implementación en la que se ejecutó, como se indica en la pregunta: si no fuera por 6.2.5 20, citado en el último párrafo, podría no compilarse. 6.2.5 23 tampoco es relevante; nos dice que el tamaño es conocido y constante si está completo, y ya sabemos que estar completo significa que se conoce el tamaño.int
deben tener el mismo tamaño entre sí, y todos los punteros a matrices de ciertostruct
deben tener el mismo tamaño entre sí, aunque quizás no todos los punteros a matrices de diferentes tiposstruct
deben tener el mismo tamaño como el uno al otro.T(*)[]
debe tener el mismo tamaño queT(*)[5]
, ya que son tipos compatibles y podríamos agregar o eliminar calificadores