Указатель на массив структур вперед объявлены в С

голоса
1

У меня есть вопрос о форвардных декларациях в C. Код проблемы является

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

После того, как код скомпилирован с GCC, он жалуется:

Ошибка: тип массива имеет «» t_yhash неполный тип элемента {иначе «структура yhash_s»}

Я понимаю, что t_yhash не знают (пока) и размер массива не может быть вычислен, но я прошу о указателе на массив неизвестного размера еще, что должно быть совершенно разрешим ИМХО.

Как исправить это опережающее объявление и STRUCT себя?

Задан 13/01/2020 в 23:59
источник пользователем
На других языках...                            


2 ответов

голоса
4

Проблема состоит в том , что declarators массива может не иметь неполный типа как тип элемента (C11 6.7.6.2/1). И t_yash(то есть struct yhash_s) не завершено до закрывающей скобки определения структуры.

Это правило также отвечает за другой кусок мелочи; это законно иметь (до определения структуры является полным):

void func( t_yhash *a );

но не законно иметь:

void func( t_yhash a[] );

даже несмотря на то, правило корректировки будет работать нормально, если бы не правило неполного типа элемента.

Вероятно, язык дизайн может быть немного улучшен путем уточнения этого правила, чтобы некоторые случаи, как в прототипе функции, но это явно не то, что возникло с дизайном комитетом языка.

Но даже без этого правила, ваш случай использования может иметь другую проблему; размер указателя не может быть известно. Было бы законным (хотя вряд ли на практике) для «указателя на массив структур X», чтобы иметь различный размер, чем «указатель на массив структур Y». Существует правило, что все указатели на структуру должны иметь одинаковый размер, но нет такого правила для указателей на массив.

Ответил 14/01/2020 в 00:24
источник пользователем

голоса
0

В ответ на эту часть вашего поста:

Как исправить это опережающее объявление и STRUCT себя?

Вы можете использовать , void *чтобы спрятать свой массив, а затем преобразовать его обратно позже.

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

Если синтаксис функции слишком тупой:

typedef t_yhash t_yhash_array[];

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

Например:

t_yhash x[10];
t_yhash y = { 10, &x };
assert(yhash(y) == &x);
Ответил 14/01/2020 в 01:38
источник пользователем

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