views:

554

answers:

5

I have code in my header file that looks like:

typedef struct _bn bnode;

I can do

bnode b;

just fine, but

b[i], where i is an int gives me the following error:

invalid use of undefined type ‘struct _bn’

Any ideas?

+1  A: 

Sounds like you either want an opaque pointer/PIMPL implementation, or you should include the appropriate header file.

Structs in C++ are almost identical to classes, so the same techniques apply.

tfinniga
I rather not use an opaque pointer in the way described in that article because it might confuse the user of the function into thinking it's a value type.
joemoe
+4  A: 

As stated, b is not an array and, as such, can not be accessed as one.

Also, how do you expect the compiler to figure out the size of that structure? When you do something like bnode b[i] a certain amount of space is to be set aside for later use. As you have it there no size.

What is your opacity intended to do for you? Maybe if you explain further what you are trying to accomplish you will get a more revealing answer...

ezpz
Yes you are right. I realized that sizeof() is not really possible and thus b[i] can't work.
joemoe
Ah, I had interpreted the brackets as an overloaded operator[] call.
tfinniga
@joemoe You might look into using something like a `void*` or similar mechanisms.
ezpz
@tfinniga Yes, it was ambiguous so I tried to cover both situations.
ezpz
A: 

You have to at least know the size of bnode to be able to make an array of them.

You could do, in your opaque definition of bnode:

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

Then you can do:

bnode b[10];

and it will work.

smcameron
+1  A: 

You can't define an array of opaque structs. If you do you get an error such as:

error: array type has incomplete element type

(the specific error text will vary; the one above is from gcc 4.4.1).

But what you can do is create an array of pointers to opaque structs. This is doable as the details of the struct do not affect the size of the pointer.

typedef struct _bn bnode;
bnode *b[20];
R Samuel Klatchko
This is the usual way of operating on opaque structs.
caf
+1  A: 

As far as an API/library goes, normally if you're going to need an opaque structure, you don't allow the user of the API to declare things like arrays or static instances because of this. Not knowing anything about the structure is the name of the game so you're probably going to have to define some functions to manipulate them. Most C libraries that declare opaque structures often has accessor and modification functions.

One example is from Lua (obviously a Lua state is an single use structure but it's the idea):

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

In this case, if you decided you needed multiple Lua states, you would do something like the following:

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

I think the general rule-of-thumb is that if you're working with opaque structures, you're going to be working through pointers only, which is pretty much the only way to go about it anyway.

Nick Bedford