int main()
{
// forward declaration
struct myStruct_st *mS; // Note that this will expand as "struct struct myStruct_st *mS which does not make any sense to me"
return 0;
}
// definition of myStruct_s
typedef struct myStruct_s
{
int x;
int y;
} myStruct_st;
I understand that myStruct_s is the structure that needs to be forward declared. I had this typo in my code which seemed to compile. I wonder how though. Does anyone know?
The local struct has nothing to do with the struct defined outside of main(). In main() you (forward-)declare a struct, define a pointer to that struct and never define the struct. That's perfectly OK. It so happens that you define a struct with the same name outside main().
I think you misunderstand how the typedef works -- it is not macro substitution.
In particular, using struct myStruct_s after the typedef is not the same as "struct struct myStruct_s" -- it's simply struct myStruct_s, as it reads on the face. The typedef introduces a token which can be used rather than struct ..., but it doesn't expand like a macro and it doesn't "wipe out" the struct ... declaration, which can still be used.
Related
I'm trying to forward declare struct_A and use it within struct_B not as a pointer but as a structure.
Within struct_B, I make reference to struct_B.
I can't seem to get it right - help?
Here's my code:
struct type_A_t;
typedef struct type_A_t type_A_t;
typedef struct type_B_t {
type_A_t a;
};
struct type_A_t{
void (*cb)(type_B_t *b1);
void (*cb)(type_B_t *b2);
};
The error I get is:
error: field 'type_A_t' has incomplete type
You can't do that. But in your example, since type_A_t only needs to know about pointers to type_B_t, why not switch it around like this?
typedef struct type_B_t type_B_t;
typedef struct type_A_t type_A_t;
struct type_A_t {
void(*cb)(type_B_t *b1);
void(*cb)(type_B_t *b2);
};
typedef struct type_B_t {
type_A_t a;
};
That is not possible. To use a type as a member, the type's size must be known, so it must be fully defined. Otherwise, sizeof(struct type_B_t) would be unknown after its definition, which makes no sense.
I can't seem to get it right - help?
Because it cannot be done.
The compiler doesn't know the size of that struct.
A forward declaration is enough for pointers though:
typedef struct type_B_t {
type_A_t a; // error
type_A_t* a; // OK
};
Of course, if in your real code, you can switch the order, as #Blaze's answer mention, then do that.
I am trying to understand struct usage in a piece of code. It is very confusing to me. looks like typedef is used twice on same struct. please can anyone help me understand why this code has typedef twice. is there any way to simplify this code.
thanks so much for your time.
typedef struct {
city_t* cities;
int count;
cost_t cost;
} tour_struct;
typedef tour_struct* tour_t;
typedef struct {
tour_t* list;
int list_sz;
int list_alloc;
} stack_struct;
typedef stack_struct* my_stack_t;
The first typedef gives the (anonymous) struct a typename. The second typedef defines a type of a pointer to the other.
tour_struct tour; // declares a struct.
tour_t ptr; // declares a pointer to a struct.
First typedef is used in a typical way to declare structs in C.
I guess You are referring to second typedef:
typedef tour_struct* tour_t;
it is used because here is declared "another name" (alias) for a pointer to aboved declared struct. This is why second typedef has been used.
using a * after a known type in typedef simply defines a pointer to that type.
typedef stack_struct* my_stack_t;
will define a pointer to stack_struct and will call it my_stack_t.
What I want to accomplish: I want to use a typedef'd function pointer inside of a typedef'd struct where the function pointer takes a struct pointer as an argument (i.e. something like an 'object method' which takes a self-reference to the 'object').
I have this C code (simplified, hopefully not oversimplified):
typedef struct MYSTRUCT myStruct;
typedef void (*getSomething)(myStruct*);
typedef struct MYSTRUCT {
getSomething get_something;
};
void get_property() {
myStruct *structure = NULL;
}
So what I think I'm doing is: forward declare the struct, use that declaration in the function pointer typedef, then declare the actual struct using the typedef'd function pointer.
This code compiles with the intel compiler on linux (and seems to do the intended thing) but the Visual compiler throws an error:
error C2275: 'myStruct' : illegal use of this type as an expression
see declaration of myStruct
Is there a way to make the VC accept my intended construct?
typedef struct MYSTRUCT {
getSomething get_something;
};
should be
struct MYSTRUCT {
getSomething get_something;
};
struct MYSTRUCT; // Forward declare the struct
typedef struct MYSTRUCT myStruct; // define the typedef;
typedef void (*getSomething)(myStruct*); // use the typedef;
struct MYSTRUCT { // define the struct
getSomething get_something;
};
void get_property() { // use the typedef again.
myStruct *structure = NULL;
}
// Warning: I didn't actually compile that, and I'm going from memory.
Sorry. I just realized this was not a problem of my forward declaration but rather because what I really did in my actual code was this:
void get_property() {
some = assignment_statement;
myStruct *structure = NULL;
}
I.e. I accidentally put my variable declaration + definition below the first code statement. So indeed, I had oversimplified my code fragment. Sorry for this.
I wrote a small code in C in which two struct types were defined which have members of each other in their definition. Case 1: If the struct foo is defined before struct bar, the code is compiled as expected. Case 2: If struct foo is defined after struct bar it will not compile which is also expected as there is no way to know the memory requirement of a struct foo variable. But I was expecting it will compile if a forward declaration of struct foo is used in case 2. But it does not work. What am I missing?
#include<stdio.h>
#include<stdlib.h>
struct foo; // forward declaration
struct bar
{
int a;
struct bar *next;
struct foo ch;
};
struct foo
{
struct bar *n;
struct foo *nx;
};
int main()
{
struct bar p;
return(0);
}
forward declaration only informs the compiler that there is something that is called foo it does nothing says about size.
you can use foo* since this is a pointer of known size but not foo itself because the size is unknwon, so the compiler does not know how the memory layout of barshould look like.
And the compiler only do a single pass through your document. so it cannot know the strucutre that is defined ahead.
If a struct type X appears only as a pointer type in a structure declaration or its functions, and the code in the header file does not attempt to access any member variables of X, then you should not #include X.h, but instead make an incomplete declaration of X (also called a
"forward" declaration) before the first use of X. Here is an example in which a structure type Thing refers to X by a pointer:
struct X; /* incomplete ("forward") declaration */
struct Thing {
int i;
struct X* x_ptr;
};
The compiler will be happy to accept code containing pointers to an incompletely known structure type, basically because pointers always have the same size and characteristics regardless of what they are pointing to. Typically, only the code in the .c file needs to access the members (or size) of X, so the .c file will #include "X.h". This is a powerful technique for encapsulating a module and decoupling it from other modules.
That is, it would work correctly if your code was something like :
#include<stdio.h>
#include<stdlib.h>
struct foo; // forward declaration
struct bar
{
int a;
struct bar *next;
struct foo *ch; /* MODIFIED LINE */
};
struct foo
{
struct bar *n;
struct foo *nx;
};
int main()
{
struct bar p;
return(0);
}
But in your case, struct bar is having an "element" of type struct foo. Hence it will give error field has incomplete type.
Also for your information, see the below snippet (will work perfectly):
#include<stdio.h>
#include<stdlib.h>
struct bar
{
int a;
struct aabar *next; /* MODIFIED LINE - aabar never declared */
struct foo *ch;
};
struct foo
{
struct bar *n;
struct foo *nx;
};
int main()
{
struct bar p;
return(0);
}
A declaration also can't let the compiler know how to allocate the memory.
In your struct foo the element nx is a pointer, so defining struct foo doesn't require memery size. However, on struct bar the element ch is not a pointer, so the defining struct bar needs to know the size of struct foo. The forward declaration doesn't specify the memory size, the definition does.
I've seen C structs declared several different ways before. Why is that and what, if anything, does each do different?
For example:
struct foo {
short a;
int b;
float c;
};
typedef struct {
short d;
int e;
float f;
} bar;
typedef struct _baz {
short a;
int b;
float c;
} baz;
int main (int argc, char const *argv[])
{
struct foo a;
bar b;
baz c;
return 0;
}
Well, the obvious difference is demonstrated in your main:
struct foo a;
bar b;
baz c;
The first declaration is of an un-typedefed struct and needs the struct keyword to use. The second is of a typedefed anonymous struct, and so we use the typedef name. The third combines both the first and the second: your example uses baz (which is conveniently short) but could just as easily use struct _baz to the same effect.
Update: larsmans' answer mentions a more common case where you have to use at least struct x { } to make a linked list. The second case wouldn't be possible here (unless you abandon sanity and use a void * instead) because the struct is anonymous, and the typedef doesn't happen until the struct is defined, giving you no way to make a (type-safe) pointer to the struct type itself. The first version works fine for this use, but the third is generally preferred in my experience. Give him some rep for that.
A more subtle difference is in namespace placement. In C, struct tags are placed in a separate namespace from other names, but typedef names aren't. So the following is legal:
struct test {
// contents
};
struct test *test() {
// contents
}
But the following is not, because it would be ambiguous what the name test is:
typedef struct {
// contents
} test;
test *test() {
// contents
}
typedef makes the name shorter (always a plus), but it puts it in the same namespace as your variables and functions. Usually this isn't an issue, but it is a subtle difference beyond the simple shortening.
It's largely a matter of personal preference. I like to give new types a name starting with a capital letter and omit the struct, so I usually write typedef struct { ... } Foo. That means I cannot then write struct Foo.
The exception is when a struct contains a pointer to its own type, e.g.
typedef struct Node {
// ...
struct Node *next;
} Node;
In this case you need to also declare the struct Node type, since the typedef is not in scope within the struct definition. Note that both names may be the same (I'm not sure where the underscore convention originated, but I guess older C compilers couldn't handle typedef struct X X;).
All your uses are syntactically correct. I prefer the following usage
/* forward declare all structs and typedefs */
typedef struct foo foo;
.
.
/* declare the struct itself */
struct foo {
short a;
int b;
foo* next;
};
Observe that this easily allows to use the typedef already inside the declaration of the struct itself, and that even for struct that reference each other mutually.
The confusion comes about because some of the declarations are in fact declaring up to three C constructs. You need to keep in mind the difference between:
A typedef declaration,
A struct definition, and
A struct declaration.
They are all very different C constructs. They all do different things; but you can combine them into the one compound construct, if you want to.
Let's look at each declaration in turn.
struct foo {
short a;
int b;
float c;
};
Here we are using the most basic struct definition syntax. We are defining a C type and give it the name foo in the tag namespace. It can later be used to declare variables of that type using the following syntax:
struct foo myFoo; // Declare a struct variable of type foo.
This next declaration gives the type another name (alias) in the global namespace. Let's break it down into its components using the previous basic declaration.
typedef foo bar; // Declare bar as a variable type, the alias of foo.
bar myBar; // No need for the "struct" keyword
Now just replace "foo" with the the struct's definition and voila!
typedef struct {
short d;
int e;
float f;
} bar;
typedef struct _baz {
short a;
int b;
float c;
} baz;
The above syntax is equivalent to the following sequence of declarations.
struct _baz {
short a;
int b;
float c;
}
typedef _baz baz; // Declare baz as an alias for _baz.
baz myBaz; // Is the same as: struct _baz myBaz;