Access struct field within another struct without referring to inner struct - c

Suppose I have a struct that is defined as the following:
struct entity {
int x;
int y;
};
And a struct that uses it as a member:
struct player {
struct entity position;
char* name;
};
If I write the following code then I get an error:
struct player p;
p.x = 0; //error: 'struct player' has no member named 'x'
What I have been doing so far is writing a function that takes a player struct and returns the value by doing return player.position.x.
Is there a compiler flag, or other method, that allows me to "flatten" (I'm not sure if that's the correct phrase) the struct and allows me to access the x variable like I have shown above? I realize that this might be ambiguous if there is also an integer named x inside player as well as in entity.
Please note I will be using the entity struct in multiple structs and so I cannot use a anonymous struct inside player.

Put succinctly, the answer is "No". This is especially true if you've looked at questions such as What are anonymous structs and unions useful for in C11 and found them not to be the solution.
You can look at C11 §6.7.2.1 Structure and union specifiers for more information about structure and union types in general (and ¶13 specifically for more information about anonymous members, and ¶19 for an example). I agree that they are not what you're after; they involve a newly defined type with no tag and no 'declarator list'.

Using a macro, we can make a type generator:
#define struct_entity(...) \
struct __VA_ARGS__ { \
int a; \
int b; \
}
Then we can instantiate that type as either a tagged or anonymous structure, at will:
struct_entity(entity);
struct player {
struct_entity();
const char *name;
};
int main() {
struct player player;
player.a = 1;
player.b = 2;
player.name = "bar";
}
This code is closer in intent to what you want, and doesn't have the UB problem of the approach of declaring just the structure members in the macro. Specifically, there is a structure member inside of struct player, instead of individual members. This is important, because padding reduction and reordering of members may be performed by the compiler - especially on embedded targets. E.g. composite_1 and composite_2 below do not necessarily have the same layout!:
#include <assert.h>
#include <stddef.h>
typedef struct sub_1 {
int a;
void *b;
char c;
} sub_1;
typedef struct sub_2 {
void *d;
char e;
} sub_2;
typedef struct composite_1 {
int a;
void *b;
char c;
void *d;
char e;
} composite_1;
typedef struct composite_2 {
struct sub_1 one;
struct sub_2 two;
} composite_2;
// Some of the asserts below may fail on some architectures.
// The compile-time asserts are necessary to ensure that the two layouts are
// compatible.
static_assert(sizeof(composite_1) == sizeof(composite_2), "UB");
static_assert(offsetof(composite_1, a) == offsetof(composite_2, one.a), "UB");
static_assert(offsetof(composite_1, b) == offsetof(composite_2, one.b), "UB");
static_assert(offsetof(composite_1, c) == offsetof(composite_2, one.c), "UB");
static_assert(offsetof(composite_1, d) == offsetof(composite_2, two.d), "UB");
static_assert(offsetof(composite_1, e) == offsetof(composite_2, two.e), "UB");

You can define then as MACROs:
#define ENTITY_MEMBERS int x; int y
struct entity{
ENTITY_MEMBERS;
}
struct player {
ENTITY_MEMBERS;
char* name;
};
Actually this is how you mimic C++ single inheritance in C.

Related

typedef, structure and type compatibiliy

If I have these two structs:
struct
{
int x;
} A;
struct
{
int x;
} B;
then making A = B; results in a compilation error because the two anonymous structs are not compatible.
However if I do:
typedef struct
{
int x;
} S;
S A;
S B;
A = B; is a legal assignment because they are compatible.
But why? With typedef I understand that the compiler makes this when meet S A and S B:
struct { int x; } A;
struct { int x; } B;
so A and B should not be compatible...
Each anonymous struct declaration is a distinct type; this is why you get a type mismatch when trying to assign one to the other.
A typedef, however, declares an alias (i.e. a new name for something that already exists) for a type (it does not create a new type).
A typedef is also not a simple text replacement, like a preprocessor macro. Your statement
I understand that the compiler make this when meet S A and S B:
struct { int x; } A;
struct { int x; } B;
is where your understanding is wrong.
When you use the type alias S, as in
S A;
S B;
the types of both objects A and B are the same by definition and assigning one to the other is possible.
This is because C treats every untagged struct as a new kind of struct, regardless of the memory layout. However, typedef struct { } name; cannot be used if you want to use the struct in a linked list. You'll need to stick with defining a structure tag in this case, and typedef the tagged struct instead.
struct DistanceInMeter /* Anonymous 1 */
{
int x; /* distance */
};
struct VolumeInCC /* Anonymous 2 */
{
int x; /* volume */
};
struct DistanceInMeter A;
struct VolumeInCC B;
...
A = B; /* Something is wrong here */
Equating different type doesn't always make sense and thus is not allowed.
typedef struct DistanceInMeter /* Anonymous 1 */
{
int x; /* distance */
} Dist_t;
Dist_t C, D;
...
C = D; /* Alright, makes sense */

What is 'forward declaration' and the difference between 'typedef struct X' and 'struct X'?

I am a beginner in C programming and I know the difference between struct type declaration and typedef struct declaration. I came across to know an answer saying that if we define a struct like:
typedef struct {
some members;
} struct_name;
Then it will be like providing an alias to an anonymous struct (as it is not having a tag name). So it can't be used for forward declaration. I don't know what the forward declaration means.
Also, I wanted to know that for the following code:
typedef struct NAME {
some members;
} struct_alias;
Is there any difference between NAME and struct_alias? Or are both equal as
struct_alias is an alias of struct NAME ?
Furthermore, can we declare a variable of type struct NAME like these:
struct_alias variable1;
and/or like:
struct NAME variable2;
or like:
NAME variable3;
struct forward declarations can be useful when you need to have looping struct declarations. Example:
struct a {
struct b * b_pointer;
int c;
};
struct b {
struct a * a_pointer;
void * d;
};
When struct a is declared it doesn't know the specs of struct b yet, but you can forward reference it.
When you typedef an anonymous struct then the compiler won't allow you to use it's name before the typedef.
This is illegal:
struct a {
b * b_pointer;
int c;
};
typedef struct {
struct a * a_pointer;
void * d;
} b;
// struct b was never declared or defined
This though is legal:
struct a {
struct b * b_pointer;
int c;
};
typedef struct b {
struct a * a_pointer;
void * d;
} b;
// struct b is defined and has an alias type called b
So is this:
typedef struct b b;
// the type b referes to a yet undefined type struct b
struct a {
b * struct_b_pointer;
int c;
};
struct b {
struct a * a_pointer;
void * d;
};
And this (only in C, illegal in C++):
typedef int b;
struct a {
struct b * struct_b_pointer;
b b_integer_type;
int c;
};
struct b {
struct a * a_pointer;
void * d;
};
// struct b and b are two different types all together. Note: this is not allowed in C++
Forward declaration is a promise to define something that you make to a compiler at the point where the definition cannot be made. The compiler can use your word to interpret other declarations that it would not be able to interpret otherwise.
A common example is a struct designed to be a node in a linked list: you need to put a pointer to a node into the struct, but the compiler would not let you do it without either a forward declaration or a tag:
// Forward declaration
struct element;
typedef struct {
int value;
// Use of the forward declaration
struct element *next;
} element; // Complete definition
and so it cant be used for forward declaration
I think that author's point was that giving your struct a tag would be equivalent to a forward declaration:
typedef struct element {
int value;
// No need for a forward declaration here
struct element *next;
} element;
Forward declaration is a declaration preceeding an actual definition, usually for the purpose of being able to reference the declared type when the definition is not available. Of course, not everything may be done with the declared-not-defined structure, but in certain context it is possible to use it. Such type is called incomplete, and there are a number of restrictions on its usage. For example:
struct X; // forward declaration
void f(struct X*) { } // usage of the declared, undefined structure
// void f(struct X) { } // ILLEGAL
// struct X x; // ILLEGAL
// int n =sizeof(struct X); // ILLEGAL
// later, or somewhere else altogether
struct X { /* ... */ };
This can be useful e.g. to break circular dependencies, or cut down the compilation time, as the definitions are usually significantly larger, and so more resources are required to parse it.
In your example, struct NAME and struct_alias are indeed equivalent.
struct_alias variable1;
struct NAME variable2;
are correct;
NAME variable3;
is not, as in C the struct keyword is required.
struct_alias and struct NAME are same ,struct_alias is an alias to struct NAME
These both are same and allowed
struct_alias variable1;
struct NAME variable1;
this is illegal
NAME variable3;
See this article on Forward declaration
As others stated before, a forward declaration in C/C++ is the declaration of something with the actual definition unavailable. Its a declaration telling the compiler "there is a data type ABC".
Lets pretend this is a header for some key/value store my_dict.h :
...
struct my_dict_t;
struct my_dict_t* create();
char* get_value(const struct my_dict_t* dict, const char* name);
char* insert(struct my_dict_t* dict, const char* name, char* value);
void destroy(struct my_dict_t* dict);
...
You dont know anything about my_dict_t, but actually, for using the store
you dont need to know:
#include "my_dict.h"
...
struct my_dict_t* dict = create();
if(0 != insert(dict, "AnEntry", strdup("AValue"))) {
...
}
...
The reason for this is: You are only using POINTERS to the data structure.
POINTERS are just numbers, and for dealing with them you dont need to know what they are pointing at.
This will only matter if you try to actually access them, like
struct my_dict_t* dict = create();
printf("%s\n", dict->value); /* Impossible if only a forward decl is available */
So, for implementing the functions, you require an actual definition of my_struct_t.
You might do this in the source file my_dict.c like so:
#include "my_dict.h"
struct my_dict_t {
char* value;
const char* name;
struct my_dict_t* next;
}
struct my_dict_t* create() {
return calloc(1, sizeof(struct my_dict_t));
}
This is handy for several situations, like
For resolving circular type dependencies, like Sergei L. explained.
For encapsulation, like in the example above.
So the question that remains is: Why cant we just omit the forward declaration at all when using the functions above? In the end, it would suffice for the compiler to know that all dict are pointers.
However, the compiler does perform type checks:
It needs to verify that you don't do something like
...
int i = 12;
char* value = get_value(&i, "MyName");
...
It does not need to know how my_dict_t looks like, but it needs to know that &i is not the type of pointer get_value() expects.

When are anonymous structs and unions useful in C11?

C11 adds, among other things, 'Anonymous Structs and Unions'.
I poked around but could not find a clear explanation of when anonymous structs and unions would be useful. I ask because I don't completely understand what they are. I get that they are structs or unions without the name afterwards, but I have always (had to?) treat that as an error so I can only conceive a use for named structs.
Anonymous union inside structures are very useful in practice. Consider that you want to implement a discriminated sum type (or tagged union), an aggregate with a boolean and either a float or a char* (i.e. a string), depending upon the boolean flag. With C11 you should be able to code
typedef struct {
bool is_float;
union {
float f;
char* s;
};
} mychoice_t;
double as_float(mychoice_t* ch)
{
if (ch->is_float) return ch->f;
else return atof(ch->s);
}
With C99, you'll have to name the union, and code ch->u.f and ch->u.s which is less readable and more verbose.
Another way to implement some tagged union type is to use casts. The Ocaml runtime gives a lot of examples.
The SBCL implementation of Common Lisp does use some union to implement tagged union types. And GNU make also uses them.
A typical and real world use of anonymous structs and unions are to provide an alternative view to data. For example when implementing a 3D point type:
typedef struct {
union{
struct{
double x;
double y;
double z;
};
double raw[3];
};
}vec3d_t;
vec3d_t v;
v.x = 4.0;
v.raw[1] = 3.0; // Equivalent to v.y = 3.0
v.z = 2.0;
This is useful if you interface to code that expects a 3D vector as a pointer to three doubles. Instead of doing f(&v.x) which is ugly, you can do f(v.raw) which makes your intent clear.
struct bla {
struct { int a; int b; };
int c;
};
the type struct bla has a member of a C11 anonymous structure type.
struct { int a; int b; } has no tag and the object has no name: it is an anonymous structure type.
You can access the members of the anonymous structure this way:
struct bla myobject;
myobject.a = 1; // a is a member of the anonymous structure inside struct bla
myobject.b = 2; // same for b
myobject.c = 3; // c is a member of the structure struct bla
Another useful implementation is when you are dealing with rgba colors, since you might want access each color on its own or as a single int.
typedef struct {
union{
struct {uint8_t a, b, g, r;};
uint32_t val;
};
}Color;
Now you can access the individual rgba values or the entire value, with its highest byte being r. i.e:
int main(void)
{
Color x;
x.r = 0x11;
x.g = 0xAA;
x.b = 0xCC;
x.a = 0xFF;
printf("%X\n", x.val);
return 0;
}
Prints 11AACCFF
I'm not sure why C11 allows anonymous structures inside structures. But Linux uses it with a certain language extension:
/**
* struct blk_mq_ctx - State for a software queue facing the submitting CPUs
*/
struct blk_mq_ctx {
struct {
spinlock_t lock;
struct list_head rq_lists[HCTX_MAX_TYPES];
} ____cacheline_aligned_in_smp;
/* ... other fields without explicit alignment annotations ... */
} ____cacheline_aligned_in_smp;
I'm not sure if that example strictly necessary, except to make the intent clear.
EDIT: I found another similar pattern which is more clear-cut. The anonymous struct feature is used with this attribute:
#if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__)
#define __randomize_layout __attribute__((randomize_layout))
#define __no_randomize_layout __attribute__((no_randomize_layout))
/* This anon struct can add padding, so only enable it under randstruct. */
#define randomized_struct_fields_start struct {
#define randomized_struct_fields_end } __randomize_layout;
#endif
I.e. a language extension / compiler plugin to randomize field order (ASLR-style exploit "hardening"):
struct kiocb {
struct file *ki_filp;
/* The 'ki_filp' pointer is shared in a union for aio */
randomized_struct_fields_start
loff_t ki_pos;
void (*ki_complete)(struct kiocb *iocb, long ret, long ret2);
void *private;
int ki_flags;
u16 ki_hint;
u16 ki_ioprio; /* See linux/ioprio.h */
unsigned int ki_cookie; /* for ->iopoll */
randomized_struct_fields_end
};
Well, if you declare variables from that struct only once in your code, why does it need a name?
struct {
int a;
struct {
int b;
int c;
} d;
} e,f;
And you can now write things like e.a,f.d.b,etc.
(I added the inner struct, because I think that this is one of the most usages of anonymous structs)

What is this operator(->) in C? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Arrow operator (->) usage in C
As far as i know only C++ can use classes(obj->something) however i have seen this operator in numerous C applications.
And a small side-question. Usually one uses structures in C like this:
structname.somevariable
However i have seen them used like:
structname.something1.something2
Does it have something to do with the keyword union?
struct A
{
int b;
};
struct A *a;
a->b == (*a).b;
And no, that has nothing to do with unions. It's just getting a member of a member.
if you have a pointer to a struct object, like
struct P * p;
you access members with ->
p->member
if p is not a pointer, you access members with .
struct P p;
p.member
Any C book covers this :P
Operator -> is used to access a member of a struct through a pointer to that structure. The second part of your question is used when accessing nested structures, it is not restricted to the use of unions. For instance:
struct A {
int a;
};
struct B {
struct A baz;
};
int main()
{
struct A foo;
struct B bar;
(&foo)->a = 10;
bar.baz.a = 20;
return 0;
}
C++ classes are an extension of C structs, and an object is just a pointer to a struct. C++ didn't actually invent a whole lot of new stuff; it's called C ++ for a reason.
structs can be nested. Given
struct a {
int a_a;
int a_b;
}
struct b {
int b_a;
struct a b_b;
} a;
you can refer to a.b_b.a_b.
A union uses similar syntax to a struct, but all the members overlap each other. This is useful when you need to interpret a chunk of memory in multiple ways.
I strongly suggest picking up a C book.
x.y.z is used when you want to access a member of a struct that is itself a member of another struct.
typedef struct _POINT
{
int x;
int y;
} POINT;
typedef struct _RECT
{
POINT topLeft;
POINT bottomRight;
} RECT;
int main()
{
RECT r;
r.topLeft.x = 0;
t.topLeft.y = 0;
int width = r.bottomRight.x - r.topLeft.x;
}
I've written a small example in C.
#include <stdio.h>
#include <stdlib.h>
struct a_t {
int a;
/* ... */
};
struct b_t {
struct a_t a;
/* ... */
};
int main()
{
struct a_t a;
struct a_t *b;
b = malloc(sizeof(struct a_t));
a.a = 1;
b->a = 2;
printf("%d; %d;\n", a.a, b->a);
(&a)->a = 3;
(*b).a = 4;
printf("%d; %d;\n", a.a, b->a);
free(b);
struct b_t c;
c.a.a = 5;
printf("%d;\n", c.a.a);
return 0;
}
If I remember correctly, in C++
class IDENTIFIER {
// stuff, possibly including functions
};
is exactly the same as
struct IDENTIFIER {
private:
// stuff, possibly including functions
};
and
struct IDENTIFIER {
// stuff, possibly including functions
};
is exactly the same as
class IDENTIFIER {
public:
// stuff, possibly including functions
};

What's the syntactically proper way to declare a C struct?

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;

Resources