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.
Related
We all know how to declare a structure in C:
struct Label1{ /* variables */ } Label2; // As I learned
But I want to know why this code works without declaring 'struct name':
typedef struct name s_name;
Or is in fact, does typing the code
struct name;
mean that I declared 'struct name' as a void structure or something like this?
Example of code:
typedef struct Data Data;
struct Data{ /*variables*/ };
If in the first line struct Data is declared as a void one, then in the second it's like I'm redeclaring it with members.
What is the explanation for this point?
Something like:
struct MyStruct;
Is called a forward reference. It creates an incomplete type and tells the compiler there will be a type of that name (and it's a struct - it works likewise for unions), and the details "follow later". Of such a type you cannot define variables, until you complete the type.
typedef struct MyStruct MyType;
Will just define the type name to be that struct. This is still an incomplete type.
However, you can take a pointer to an incomplete type:
MyType *my_t_pointer;
struct MyStruct *my_s_pointer;
This is useful for a struct to have pointers to objects of the same type when you provide the full declaration, "completing" the type:
struct MyStruct {
struct MyStruct *next;
};
Actually this is the only way to create nodes for lists, trees, and all other recursive data-structures. This is a major part of C programs (sometimes hidden).
Also, this mechanism is used to hide implementation details. Functions in the header need only know the struct exists to take/pass pointers to it. The use of these functions need not to know the details of the struct (but this way it cannot allocate it, so the module has to cover all aspects which need to know details on the struct). The full declaration is only inside the implementation file of the module.
These pointers are called "opaque" as one cannot "look through", i.e. access the fields of the struct as they are simply not known to it.
my_module.h:
struct MyStruct;
extern void my_init(struct MyStruct *obj);
my_module.c:
struct MyStruct {
int f1;
...
};
my_init(struct MyStruct *obj)
{
...
}
The typedef declares s_name as an alias for struct name so that you can declare variables, e.g.:
s_name *sptr;
The line
struct name;
declares that there is a struct type called name without defining its content. This is usually done in order to be able to declare variables as pointers to the struct type. You cannot declare variables of the actual struct type until it has been defined.
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 am doing feature enhancement on a piece of code, and here is what i saw in existing code. If there is a enum or struct declared, later there is always a typedef:
enum _Mode {
MODE1 = 0,
MODE2,
MODE3
};
typedef enum _Mode Mode;
Similary for structure:
struct _Slot {
void * mem1;
int mem2;
};
typedef struct _Slot Slot;
Can't the structures be directly declared as in enum? Why there is a typedef for something as minor as underscore? Is this a coding convention?
Kindly give good answers, because i need to add some code, and if this is a rule, i need to follow it.
Please help.
P.S: As an additional info, the source code is written in C, and Linux is the platform.
In C, to declare a varaible with a struct type you would have to use the following:
struct _Slot a;
The typedef allows you to make this look somewhat neater by essentially creating an alias. And allowing variable declaration like so:
Slot a;
In C there are separate "namespaces" for struct and typedef. Thus, without a typedef you would have to access Slot as struct _Slot, which is more typing. Compare:
struct Slot { ... };
struct Slot s;
struct Slot create_s() { ... }
void use_s(struct Slot s) { ... }
vs
typedef struct _Slot { ... } Slot;
Slot s;
Slot create_s() { ... }
void use_s(Slot s) { ... }
Also see http://en.wikipedia.org/wiki/Struct_(C_programming_language)#typedef for details, like possible namespace clash.
If the following is a structure:
struct _Slot {
void * mem1;
int mem2;
};
you need the following to declare a variable:
struct _Slot s;
Notice the extra struct before _Slot. It seems more natural to declare a variable like Slot s, isn't it?
If you want to get rid of extra struct, you need a typedef:
typedef struct _Slot Slot;
Slot s;
It's sort of code obfuscation technique which only make sense in small amount of cases.
People say it's more natural to not write "struct" and other subjective things.
But objectively, one at least a) can't forward declare such typedeffed struct, b) have to jump through one hoop when using ctags.
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.