Selhar
Selhar

Reputation: 136

Why a structure is allowed to have "pointer to its own type" as member but not "(an array of the) structure type" itself?

when i try to declare the following function

typedef struct TRIE_NODE
{
    char* word;
    struct TRIE_NODE node[26];
}TRIE_NODE;

I get the following error:

definition of 'struct TRIE_NODE' is not complete until the closing '}'

However, if i declare this function with a pointer to the 26 nodes, it compiles just fine.

typedef struct TRIE_NODE
{
    char* word;
    struct TRIE_NODE* node[26];
}TRIE_NODE;

I imagine that, since this is not an instance, it's impossible for me to get a pointer to the first of those 26 arrays, but if that is the problem, how is TRIE_NODE* node[26] not also a problem? Isn't this declaration equivalent to TRIE_NODE node[1][26]?

Upvotes: 1

Views: 255

Answers (3)

Nick
Nick

Reputation: 10539

Nobody mention this, but if struct was allowed to have member or array of itself (not a pointer, but regular member or array), then the struct would be recursive and with infinite size, because the member will have one more member inside of same type and so on until infinity.

Upvotes: 1

James K. Lowden
James K. Lowden

Reputation: 7837

To answer your own question, ask: how many bytes will

struct TRIE_NODE node[26];

occupy? In fact, what would you expect sizeof(struct TRIE_NODE) to be?

The reason

struct TRIE_NODE *node[26];

works is that we know the value of sizeof(struct TRIE_NODE*). Because all struct pointers have the same size, we can allocate an array of N struct pointers, no matter their type, even if incompletely defined.

aren't pointers and arrays almost interchangeable?

The syntax for pointers and arrays is similar. You can subscript a pointer, and you can add to an array's address. But they define different things. Basically: an array holds data, and a pointer holds an address.

In certain parts of the C standard library, you'll find structures defined like this:

struct S {
    int len;
    char data[1];
};

You might be tempted to ask why not use a pointer?

struct Z {
    int len;
    char *data;
};

Answer: struct S is actually bigger than the 5 or so bytes it seems to occupy, and the data portion begins immediately after len. In the putative struct Z example, data doesn't begin the data; the data would be somewhere else, wherever data points.

Assuming the structures are appropriate initialized, in both cases data[0] will address the first byte of the array. They're syntactically similar. But the memory layout is different. In the S case, that byte will be pretty close to (char*)&len + sizeof(len). In the Z case it will be wherever data points.

Upvotes: 1

Sourav Ghosh
Sourav Ghosh

Reputation: 134336

when i try to declare the following function

Wait!! that's not a function, that's typedef-ing a structure, a user-defined type.


That said, in the first case,

typedef struct TRIE_NODE
{
    char* word;
    struct TRIE_NODE node[26];  //array of type struct TRIE_NODE
}TRIE_NODE;

if this has to be possible, compiler needs to know the size of the struct TRIE_NODE before it has been defined, which is impossible. So it is invalid.

On th other hand,

typedef struct TRIE_NODE
{
    char* word;
    struct TRIE_NODE* node[26];  //array of pointers (of type struct TRIE_NODE)
}TRIE_NODE; 

is fine, as you're allocating (array of) pointers to the structure, the actual size of the structure is not required to be known by compiler at that point. So, the compiler happily allocates the pointers and the definition (construct) is perfectly valid.

Upvotes: 4

Related Questions