Initializing structure array inside a structure array - c

I have a question in initializing my structure array inside a structure array. for example if I have a code as below:
#include <stdio.h>
int main() {
typedef struct {
int a;
int b;
int c;
} FIRST_T;
typedef struct {
int x;
int y;
int z;
FIRST_T *p;
} SECOND_T;
FIRST_T p1[]={{1,2,3},{3,4,5},{6,7,8}};
FIRST_T p2[]={{4,5,6},{7,8,9}};
SECOND_T my_second[]=
{
{1,2,3,p1},
{4,5,6,p2}
};
}
if I have to initialize my first array in second array intialization part itself, then how would I write my typedef of SECOND_T?
like
SECOND_T my_second[]=
{
{1,2,3,{{1,2,3},{4,5,6},{7,8,9}}},
{4,5,6,{{1,1,1},{2,2,2}}}
};
then how should be my SECOND_T?
I am sure I can't define it as:
typedef struct {
int x;
int y;
int z;
FIRST_T p[]; //(I know its a blunder)
} SECOND_T;
Please help.

You can't define a type with unbounded array in C, you have to specify the dimension. So you either do:
typedef strut {
int x;
int y;
int z;
FIRST_T f[SOME_VALUE];
} SECOND_T;
and then initialize SOME_VALUE count of members always, or do it the way you did.

I don't think you can do this, i.e, initialize the FIRST_T inside the initialization of SECOND_T, other than the first way you do it. Think about it, how can the compiler tell how many FIRST_T are there in SECOND_T? The problem here is, you can NOT define an array of flexible size struct statically.

you can't to do like that:
SECOND_T my_second[]=
{
{1,2,3,{{1,2,3},{4,5,6},{7,8,9}}},
{4,5,6,{{1,1,1},{2,2,2}}}
};
with
typedef struct {
int x;
int y;
int z;
FIRST_T p[]; //(I know its a blunder)
} SECOND_T;
becase the compiler don't know how to malloc memory for this struct. if you must do like this, you should define
typedef struct { int x,y,z; FIRST_T p[CONST_VALUE];}SECOND_T;
but I advise you use the first style that you write.

I don't know if I completely capture the question that you have. If it is that you want to avoid to have to declare an auxiliary variable for the pointers in the structure you can use a compound literal as follows:
SECOND_T my_second[] = {
{1,2,3, &(FIRST_T){{1,2,3},{3,4,5},{6,7,8}}},
{4,5,6, &(FIRST_T){{4,5,6},{7,8,9}}}
};
You'd have a compiler that complies to C99 for that.

Related

C Pointer To Anonymous Struct

Is there a way to get a pointer to an anonymous struct? With out anonymous structs I could write the following:
struct a{
int z;
};
struct b{
int y;
struct a *x;
}
This works fine, but I only use struct a within struct b and it seems redundant to pollute the global namespace with it. Is there a way I could define a pointer (x) to an anonymous struct. Something that would probably look like the following:
struct b{
int y;
struct {
int z;
} *x;
}
Or is this valid on its own?
Yes you can do this. But there is a complication: there is no way to directly declare another pointer to same type - or an object of that type, because... the struct type is anonymous.
It is still possible to use it however, by allocating memory for it with malloc, as conversions from void * to any pointer to object are possible without an explicit cast:
struct b {
int y;
struct {
int z;
} *x;
} y;
y.x = malloc(sizeof *y.x * 5);
Why would you think that this is better than polluting the namespace is beyond my imagination.
GCC provides the typeof so you can increase insanity by things like
typeof(y.x) foo;
or even declare a structure of that type
struct b y;
typeof(y.x[0]) foo;
foo.z = 42;
y.x = &foo;

Nested struct in C issue

I have a struct declaration in C that looks something like this:
static struct {
int a;
int b;
} myStruct[10];
I want to declare a struct member variable inside myStruct, so I try to add this:
static struct {
int c;
int d;
struct myStruct[10] s;
} myNestedStruct[100];
I'm getting a bunch of errors i.e. syntax error before or at: [ and
syntax requires ";" after last struct/union member. What would the better way to implement the nested structs be?
EDIT: My code now looks like this:
static struct {
int a;
int b;
} myStruct[10];
static struct {
int c;
int d;
struct myStruct s[10];
} myNestedStruct[100];
However I'm getting an error: incomplete struct/union/enum myStruct: s
You need to declare myStruct first before using it as a struct type.
struct myStruct {
int a;
int b;
};
static struct {
int c;
int d;
struct myStruct s[10];
} myNestedStruct[100];
This creates a variable called myNestedStruct which is an array of 100 structs, each containing two ints and an array of 10 mystructs.
When you write code like
struct { ... } Foo;, it's not declaring a type named Foo but a variable. Its type is an anonymous struct corresponding to what you put in the curly braces. If you want to declare a type, write struct Foo { ... };.
That's where your error is coming from -- myStruct is not a type name, so when you write struct myStruct in the definition of myNestedStruct the compiler thinks you're about to define a struct by that name. But then it encounters an [ which shouldn't be the next token in a struct declaration ever so it tells you can't make sense of the code.

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 */

How to declare similar structure with different number of fields?

I have 2 headers that need to define 2 similar structures. One structure should be aligned to 32bytes and other is similar but doesn't need to align to 32bytes so I can save some memory here. One is included in the other. Here is main_header.h
struct mainStruct
{
int a;
int b;
int c;
char pad[20];
};
Following is sub_header.h
#include "main_header.h"
struct subStruct
{
int a;
int b;
int c;
};
Now what I wish to do is define subStruct in a way that, whenever i change mainStruct other than pad[20] all other fields should be updated in subStruct. That is, if tomorrow, I make mainStruct like this:
struct mainStruct
{
int a;
int b;
int c;
int d;
char pad[16];
};
then, automatically it should be reflected in sub_header.h as
struct subStruct
{
int a;
int b;
int c;
int d;
};
Is there an efficient way of doing it using some kind of Macros or other preprocessor directives??
And subStruct should always be derived from mainStruct and not other way around, this is very important.
Thanks in advance.
Did you consider the other way around; including subStruct as an element in mainStruct? Like this:
struct sub {
int a, b, c;
};
struct main {
struct sub head;
char dummy[16];
};
True, it does take an extra layer of syntax to get at a, b or c, but the memory layout and performance should be the same.
Otherwise, there's nothing preventing you from using a macro, as you suggest yourself:
#define SUB_FIELDS int a; int b; int c;
struct main {
SUB_FIELDS
char dummy[16];
};
struct sub {
SUB_FIELDS
};
Well, that's why C++ was initially invented. But if you wish to stay with plain C (there could be reasons for such decision) you may check GLib / GObject type system implemented as a set of macros over plain C.

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
};

Resources