Two way struct pointer link, C - c

Is it possible to form a two way link between structs? I tried to achieve it like this:
typedef struct
{
int foo;
b *b;
} a;
typedef struct
{
int bar;
a *a;
} b;
But the struct a does not know what b is because it's declared afterwards.

Try this,
typedef struct a a;
typedef struct b b;
struct a
{
int foo;
b *b;
} ;
struct b
{
int bar;
a *a;
} ;

When you need to reference other structs that may have not been defined up until then, make your declaration like this and it should work:
typedef struct
{
int foo;
struct b *b;
} a;
typedef struct
{
int bar;
struct a *a;
} b;

Related

Is there a way to add new members to structure in C? [duplicate]

typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo;
int b;
} bar;
Essentially I want to do:
bar b;
b.a;
I know that i could do b.foo_name.a if I had named the foo struct in bar, but Id prefer not to.
Any way to do this?
This question has gotten a variety of different answers, so let me explain the need. The reason I want to do this is because I have a library which I need to adapt to my situation, meaning that I cant modify the original struct decleration. Furthermore, all I need to do is add 1 item to the beginning of the struct (why the beginning? because I have an 'object' struct which heads all the structs in the project). I could simply embed the struct like you mention but its REALLY annoying as all references will need to be typed 'variable->image.location' that 'image.' typed a billion types is really annoying.
Evidently this feature has been added to C11, but alas I don't have access to a C compiler of recent vintage (>= GCC 4.6.2).
typedef struct foo {
int a;
} foo;
typedef struct bar {
struct foo;
int b;
} bar;
int main() {
bar b;
b.a = 42;
b.b = 99;
return 0;
}
You can, using pointers, because a pointer to a structure object is guaranteed to point its first member. See e.g. this article.
#include <stdlib.h>
#include <stdio.h>
typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo super;
int b;
} bar;
int fooGetA(foo *x) {
return x->a;
}
void fooSetA(foo *x, int a) {
x->a = a;
}
int main() {
bar* derived = (bar*) calloc(1, sizeof(bar));
fooSetA((foo*) derived, 5);
derived->b = 3;
printf("result: %d\n", fooGetA((foo*) derived));
return 0;
}
Not possible in C the way you did. But you can mimic inheritance having a foo member variable in bar.
typedef struct bar_s {
foo obj;
int b;
} bar;
bar b;
b.obj.a = 10;
If you ment
typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo my_foo;
int b;
} bar;
so you can do:
bar b; b.my_foo.a = 3;
Otherwise, There's no way of doing it in C since the sizeof(bar_s) is detriment on compile time. It's not a good practice but you can save a void * ptr; pointer within bar_s, and another enum which describes the ptr type, and cast by the type.
i.e:
typedef enum internalType{
INTERNAL_TYPE_FOO = 0,
}internalType_t;
typedef struct bar_s {
internalType_t ptrType;
void* ptr;
int b;
} bar;
and then:
bar b; foo f;
b.ptrType = INTERNAL_TYPE_FOO;
b.ptr = &f;
and some where else in the code:
if (b.ptrType == INTERNAL_TYPE_FOO) {
foo* myFooPtr = (foo *)b.ptr;
}
It can be easily done via preprocessor:
Create a file named base_foo.h:
int foo;
Then simply include it:
typedef struct foo_s {
#include "base_foo.h"
} foo;
typedef struct bar_s {
#include "base_foo.h"
int b;
} bar;
There is a confusion between anonymous structures and unions with nameless field. The nameless field is a Microsoft Extension.
struct known {
struct /* anonymous */ {
int anonymous;
};
int known;
};
An anonymous struct or union is a struct or union without any tag name that is embedded within another struct or union. It does not need to have any field names either.
A nameless field is a Microsoft Extension that allows limited inheritance in C.
struct A {
int a;
};
struct B {
struct A: // nameless field
int b;
};
Anonymous struct or union are not Nameless Fields, and Nameless Fields are not Anonymous, at least the way C11 standard defines it.
You can try using inheritance:
struct foo_s
{
int a;
};
struct bar_s: foo_a
{
int b;
};
Works in C++, not sure if it works in C.
This is the simplest way without the c flags
#include <stdio.h>
#define foo_s struct { int a; }
typedef foo_s foo;
typedef struct bar_s {
foo_s; // extends foo_s
int b;
} bar;
int main(void)
{
bar b = {
.a = 1,
.b = 2,
};
foo *f = (foo *)&b;
printf("a: %d\n", f->a);
return 0;
}
$ gcc inherit.c
$ ./a.out
a: 1

Clarification about a particular struct definition in C

I found this structure in the slides of my professor:
struct point{
int x;
int y;
} p;
What does p mean? So far I used only the classical struct like this:
struct point{
int x;
int y;
};
struct point{
int x;
int y;
} p;
defines a variable p of type struct point
it is same as
struct point{
int x;
int y;
};
struct point p;
struct point{
int a;
int b;
}p;
This is the same as using struct point p
When we use typedef struct p as in
typedef struct point{
int a;
int b;
}p;
We can use p to declare a structure pointer or structure variable later on
To create a structure pointer p *abc
To create a structure variable p xyz

How to handle circular dependencies in typedef'd structures

I have two modules, a and b.
a.h:
#ifndef A_H_
#define A_H_
#include "b.h"
typedef struct {
b_t *b;
...
} a_t;
#endif // A_H_
b.h:
#ifndef B_H_
#define B_H_
#include "a.h"
typedef struct {
a_t *a;
...
} b_t;
#endif // B_H_
How do I alter this so that it will compile? (I want to keep two separate compilation units.)
edit: I forgot to make the structure members pointers.
Use forward declarations:
a.h:
struct b_t;
typedef struct a_t {
struct b_t *b;
} a_t;
b.h:
struct a_t;
typedef struct b_t {
struct a_t *a;
} b_t;
[This answer only applies to the original question, where pointers were not used as the struct members].
that's impossible. it's naturally not possible to have such structure.
let's say:
struct a {
struct b b;
int i;
};
struct b {
struct a a;
int i;
};
what do you expect from sizeof(struct a)? this struct will explode, it's impossible to compile.
however, it can be compiled if you have them turn to pointers:
struct a;
struct b {
struct a *ap;
};
struct a {
struct b *bp;
};
this code indeed compiles: http://ideone.com/GKdUD9.
Exactly this isn't possible. You can't have a struct be its own member, not even transitively. This is however possible when you use a pointer. Use a structure declaration:
typedef struct a_struct *a_t;
typdef struct {
a_t a;
} *b_t;
typedef struct a_struct {
b_t b;
} a_t;
[This answer only applies to the original question, where pointers were not used as the struct members].
You can't.
Essentially you have
typedef struct {
b_t b;
} a_t;
typedef struct {
a_t a;
} b_t;
and no forward declaration can help you. You have an impossible structure here: the sizeof would be infinite.

Can I 'extend' a struct in C?

typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo;
int b;
} bar;
Essentially I want to do:
bar b;
b.a;
I know that i could do b.foo_name.a if I had named the foo struct in bar, but Id prefer not to.
Any way to do this?
This question has gotten a variety of different answers, so let me explain the need. The reason I want to do this is because I have a library which I need to adapt to my situation, meaning that I cant modify the original struct decleration. Furthermore, all I need to do is add 1 item to the beginning of the struct (why the beginning? because I have an 'object' struct which heads all the structs in the project). I could simply embed the struct like you mention but its REALLY annoying as all references will need to be typed 'variable->image.location' that 'image.' typed a billion types is really annoying.
Evidently this feature has been added to C11, but alas I don't have access to a C compiler of recent vintage (>= GCC 4.6.2).
typedef struct foo {
int a;
} foo;
typedef struct bar {
struct foo;
int b;
} bar;
int main() {
bar b;
b.a = 42;
b.b = 99;
return 0;
}
You can, using pointers, because a pointer to a structure object is guaranteed to point its first member. See e.g. this article.
#include <stdlib.h>
#include <stdio.h>
typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo super;
int b;
} bar;
int fooGetA(foo *x) {
return x->a;
}
void fooSetA(foo *x, int a) {
x->a = a;
}
int main() {
bar* derived = (bar*) calloc(1, sizeof(bar));
fooSetA((foo*) derived, 5);
derived->b = 3;
printf("result: %d\n", fooGetA((foo*) derived));
return 0;
}
Not possible in C the way you did. But you can mimic inheritance having a foo member variable in bar.
typedef struct bar_s {
foo obj;
int b;
} bar;
bar b;
b.obj.a = 10;
If you ment
typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo my_foo;
int b;
} bar;
so you can do:
bar b; b.my_foo.a = 3;
Otherwise, There's no way of doing it in C since the sizeof(bar_s) is detriment on compile time. It's not a good practice but you can save a void * ptr; pointer within bar_s, and another enum which describes the ptr type, and cast by the type.
i.e:
typedef enum internalType{
INTERNAL_TYPE_FOO = 0,
}internalType_t;
typedef struct bar_s {
internalType_t ptrType;
void* ptr;
int b;
} bar;
and then:
bar b; foo f;
b.ptrType = INTERNAL_TYPE_FOO;
b.ptr = &f;
and some where else in the code:
if (b.ptrType == INTERNAL_TYPE_FOO) {
foo* myFooPtr = (foo *)b.ptr;
}
It can be easily done via preprocessor:
Create a file named base_foo.h:
int foo;
Then simply include it:
typedef struct foo_s {
#include "base_foo.h"
} foo;
typedef struct bar_s {
#include "base_foo.h"
int b;
} bar;
There is a confusion between anonymous structures and unions with nameless field. The nameless field is a Microsoft Extension.
struct known {
struct /* anonymous */ {
int anonymous;
};
int known;
};
An anonymous struct or union is a struct or union without any tag name that is embedded within another struct or union. It does not need to have any field names either.
A nameless field is a Microsoft Extension that allows limited inheritance in C.
struct A {
int a;
};
struct B {
struct A: // nameless field
int b;
};
Anonymous struct or union are not Nameless Fields, and Nameless Fields are not Anonymous, at least the way C11 standard defines it.
You can try using inheritance:
struct foo_s
{
int a;
};
struct bar_s: foo_a
{
int b;
};
Works in C++, not sure if it works in C.
This is the simplest way without the c flags
#include <stdio.h>
#define foo_s struct { int a; }
typedef foo_s foo;
typedef struct bar_s {
foo_s; // extends foo_s
int b;
} bar;
int main(void)
{
bar b = {
.a = 1,
.b = 2,
};
foo *f = (foo *)&b;
printf("a: %d\n", f->a);
return 0;
}
$ gcc inherit.c
$ ./a.out
a: 1

C typedef function prototype with struct attempting to reference before defined.

I need to reference a struct that's not yet defined because the struct actually conatins the typedef'd function prototype.
For example,
typedef int (MyCallbackFunction)(X * x, void * ctx);
typedef struct CallbackData {
MyCallbackFunction * callback;
void * ctx;
} CallbackData;
typedef struct X {
char a;
int b;
int c;
double d;
CallbackData e;
} X;
What's the valid way to actually write this code/header ?
Just forward declare the relevant types - and you can make the function pointer part of the typedef:
struct X_;
typedef int (*MyCallbackFunction)(struct X_ * x, void * ctx);
typedef struct CallbackData_ {
MyCallbackFunction callback;
void * ctx;
} CallbackData;
typedef struct X_ {
char a;
int b;
int c;
double d;
CallbackData e;
} X;
Just forward declare your typedefs
typedef struct X X;
typedef struct CallbackData CallbackData;
and then declare the structs later.
Yes, you can forward declare the struct and use it in the declaration of MyCallbackFunction where you don't need it to be a complete type.
struct X;
typedef int (MyCallbackFunction)(struct X * x, void * ctx);

Resources