Как вы определяете непрозрачный массив структуры в C? - PullRequest
1 голос
/ 09 октября 2009

В моем заголовочном файле есть код, который выглядит следующим образом:

typedef struct _bn bnode;

Я могу сделать

bnode b;

просто отлично, но

b[i], где я - int, выдает мне следующую ошибку:

недопустимое использование неопределенного типа ‘struct _bn’

Есть идеи?

Ответы [ 5 ]

3 голосов
/ 09 октября 2009

Как указано, b не является массивом и, как таковой, не может быть доступен как один.

Кроме того, как вы ожидаете, что компилятор определит размер этой структуры? Когда вы делаете что-то вроде bnode b[i], определенное количество места должно быть отведено для последующего использования. Как у вас там нет размера.

Какая ваша непрозрачность предназначена для вас? Возможно, если вы объясните, что вы пытаетесь сделать, вы получите более откровенный ответ ...

1 голос
/ 10 октября 2009

Что касается API / библиотеки, обычно, если вам понадобится непрозрачная структура, вы не позволяете пользователю API объявлять такие вещи, как массивы или статические экземпляры, из-за этого. Не знать ничего о структуре - это название игры, поэтому вам, вероятно, придется определить некоторые функции для управления ими. Большинство библиотек C, которые объявляют непрозрачные структуры, часто имеют функции доступа и модификации.

Один из примеров от Lua (очевидно, что состояние Lua - это структура одноразового использования, но это идея):

typedef struct lua_State lua_State;
void lua_pushnumber(lua_State *s, lua_Number n);

В этом случае, если вы решили, что вам нужно несколько состояний Lua, вы должны сделать что-то вроде следующего:

lua_State *states[5];
for(int i = 0; i < 5; i++)
    states[i] = lua_open();

Я думаю, что общее эмпирическое правило заключается в том, что если вы работаете с непрозрачными структурами, вы будете работать только с указателями, что в любом случае является практически единственным способом сделать это.

1 голос
/ 10 октября 2009

Вы не можете определить массив непрозрачных структур. Если вы получаете сообщение об ошибке, такое как:

ошибка: тип массива имеет неполный тип элемента

(текст конкретной ошибки будет отличаться; приведенный выше от gcc 4.4.1).

Но вы можете создать массив указателей на непрозрачные структуры. Это выполнимо, поскольку детали структуры не влияют на размер указателя.

typedef struct _bn bnode;
bnode *b[20];
1 голос
/ 09 октября 2009

Звучит так, будто вам нужна либо непрозрачная указатель / реализация PIMPL , либо вы должны включить соответствующий заголовочный файл.

Структуры в C ++ почти идентичны классам, поэтому применяются те же методы.

0 голосов
/ 09 октября 2009

Вы должны хотя бы знать размер bnode, чтобы иметь возможность создать из них массив.

Вы можете сделать, в своем непрозрачном определении bnode:

typedef struct bnode_struct {
   uint8_t opaque_bytes[1024]; /* magically just "know" how big it is. */
} bnode;

Тогда вы можете сделать:

bnode b[10];

и это будет работать.

...