Um apontador para a frente matriz de estruturas em C declarado

votos
1

Eu tenho uma pergunta sobre declarações para a frente em C. O código do problema é

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

Uma vez que o código é compilado com gcc, ele reclama:

de erro: Tipo de matriz tem incompleta elemento do tipo 't_yhash' {aka 'struct yhash_s'}

Eu entendo que t_yhash não se sabe (ainda) eo tamanho da matriz não pode ser calculado, mas eu estou perguntando sobre ponteiro para uma matriz de ainda desconhecida tamanho, o que deve ser IMHO perfeitamente resolúvel.

Como faço para corrigir essa declaração para a frente e struct em si?

Publicado 13/01/2020 em 23:59
fonte usuário
Em outras línguas...                            


2 respostas

votos
4

O problema é que declarators de matriz podem não ter um tipo incompleto como o tipo de elemento (C11 6.7.6.2/1). E t_yash(isto é, struct yhash_s) não é completa até que a chave de fechamento da definição estrutura.

Esta regra também é responsável por outro pedaço de trivia; é legal ter (antes da definição struct é completa):

void func( t_yhash *a );

mas não é legal ter:

void func( t_yhash a[] );

mesmo que a regra de ajuste iria funcionar muito bem se não fosse a regra de tipo de elemento incompleto.

Provavelmente, o projeto de linguagem poderia ser melhorado ligeiramente por refinação esta regra para permitir alguns casos, como o protótipo da função, mas claramente não foi algo que surgiu com a comissão de design de linguagem.

Mas, mesmo sem essa regra, seu caso de uso pode ter outro problema; o tamanho do ponteiro pode não ser conhecido. Seria legal (embora improvável na prática) para "ponteiro para matriz de estrutura X" para ter um tamanho diferente do "ponteiro para matriz de estrutura Y". Há uma regra que todos os ponteiros para struct deve ter o mesmo tamanho, mas nenhuma regra para ponteiros para array.

Respondeu 14/01/2020 em 00:24
fonte usuário

votos
0

Em resposta a esta parte do seu post:

Como faço para corrigir essa declaração para a frente e struct em si?

Você pode usar void *para esconder a sua matriz, e depois convertê-lo novamente mais 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;
}

Se a sintaxe da função é muito obtuso:

typedef t_yhash t_yhash_array[];

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

Por exemplo:

t_yhash x[10];
t_yhash y = { 10, &x };
assert(yhash(y) == &x);
Respondeu 14/01/2020 em 01:38
fonte usuário

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