Ukazatel na pole dopředu deklarován struktury C

hlasů
1

Mám dotaz ohledně předběžných prohlášení v C. Problém číslo je

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

Jakmile je kód sestaven s gcc, to si stěžuje:

Chyba: typ pole má nekompletním typ prvku ‚t_yhash‘ {neboli ‚struct yhash_s‘}

Chápu, že t_yhash není znát (zatím) a velikost pole nemůže být počítán, ale žádám o ukazatel na pole neznámého ještě velikosti, která by měla být dokonale srozumitelný IMHO.

Jak mohu opravit, že dopředu prohlášení a struct sám?

Položena 13/01/2020 v 21:59
zdroj uživatelem
V jiných jazycích...                            


2 odpovědí

hlasů
4

Problém je v tom, že pole declarators nemusí mít neúplné typu, jako je typ prvku (C11 6.7.6.2/1). A t_yash(tedy struct yhash_s) není dokončena, dokud uzavírací závorka definice struct.

Toto pravidlo je také zodpovědný za jiný kus drobnosti; je to legální, aby (před definice struct je kompletní):

void func( t_yhash *a );

ale není legální, aby:

void func( t_yhash a[] );

i když toto pravidlo úprava bude fungovat stejně dobře, ne-li pro pravidlo neúplného typu element.

Pravděpodobně jazyk návrh by mohl být mírně zlepšila rafinací toto pravidlo umožní některé případy, jako prototyp funkce, ale to zjevně nebylo něco, který vznikl s návrhem výboru jazyka.

Ale i bez tohoto pravidla, váš případ užití může mít další problém; velikost ukazatele nemusí být známa. To by bylo legální (i když nepravděpodobné, že v praxi) pro „ukazatel na pole struct X“ mají jinou velikost, než „ukazatel na pole struct Y“. Existuje pravidlo, že všechny ukazatele na struct musí mít stejnou velikost, ale žádné takové pravidlo pro ukazatele na pole.

Odpovězeno 13/01/2020 v 22:24
zdroj uživatelem

hlasů
0

V odpovědi na tuto část svého příspěvku:

Jak mohu opravit, že dopředu prohlášení a struct sám?

Můžete použít void *k ukrývat své pole, a pak ji převést zpět později.

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;
}

V případě, že syntax funkce je příliš tupý:

typedef t_yhash t_yhash_array[];

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

Například:

t_yhash x[10];
t_yhash y = { 10, &x };
assert(yhash(y) == &x);
Odpovězeno 13/01/2020 v 23:38
zdroj uživatelem

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