Un puntero a la matriz de adelante declaró estructuras en C

votos
1

Tengo una pregunta acerca de declaraciones adelantadas en C. El código de problema es

typedef struct yhash_s t_yhash;                          // forward declaration
struct yhash_s {
               size_t  size_h; 
               t_yhash (*yhash)[]                        // pointer to array of structures
               };

Una vez que el código se compila con gcc, se queja:

error: tipo de matriz tiene incompleta tipo de elemento 't_yhash' {aka 'struct yhash_s'}

Entiendo que t_yhash no se sabe (aún) y el tamaño de la matriz no puede ser calculado, pero estoy preguntando por puntero a una matriz de tamaño desconocido sin embargo, que debe ser perfectamente resolubles en mi humilde opinión.

¿Cómo puedo solucionar esa declaración hacia adelante y estructura en sí?

Publicado el 13/01/2020 a las 23:59
fuente por usuario
En otros idiomas...                            


2 respuestas

votos
4

El problema es que declaradores de matriz pueden no tener un tipo incompleto como el tipo de elemento (C11 6.7.6.2/1). Y t_yash(es decir struct yhash_s) no es completa hasta que la llave de cierre de la definición de estructura.

Esta regla también es responsable de otro pedazo de curiosidades; Es legal tener (antes de la definición struct es completa):

void func( t_yhash *a );

pero no legal de tener:

void func( t_yhash a[] );

a pesar de que la regla de ajuste funcionaría bien si no fuera por la regla de tipo de elemento incompleta.

Probablemente el diseño de lenguajes podría mejorar ligeramente mediante el refinado de esta regla para permitir que algunos casos como el prototipo de función, pero está claro que no fue algo que surgió con el comité de diseño del lenguaje.

Pero incluso sin esta regla, su caso de uso podría tener otro problema; el tamaño del puntero no podría ser conocido. Sería legal (aunque poco probable en la práctica) para "puntero a la matriz de struct X" para tener un tamaño diferente de "puntero a la matriz de struct Y". Hay una regla que todos los punteros a struct deben tener el mismo tamaño, pero no hay tal regla para los punteros a la matriz.

Respondida el 14/01/2020 a las 00:24
fuente por usuario

votos
0

En respuesta a esta parte de su mensaje:

¿Cómo puedo solucionar esa declaración hacia adelante y estructura en sí?

Se puede utilizar void *para guardar la matriz, y luego convertirlo de nuevo más tarde.

typedef struct yhash_s t_yhash;
struct yhash_s {
               size_t  size_h;
               void *yhash;
               };

static inline t_yhash (*yhash(t_yhash y))[] {
    return y.yhash;
}

Si la sintaxis de la función es demasiado obtuso:

typedef t_yhash t_yhash_array[];

static inline t_yhash_array *yhash(t_yhash y) {
    return y.yhash;
}

Por ejemplo:

t_yhash x[10];
t_yhash y = { 10, &x };
assert(yhash(y) == &x);
Respondida el 14/01/2020 a las 01:38
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more