Nested Structure formatting in C - c

I come across a nested structure & union with the following syntax. I am not sure how the following syntax needs to be corrected.
typedef struct 1
{
..
..
union
{
struct
{
..
..
}var1;
struct
{
...
...
...
}var2;
}
..
..
}name_to_struct1
Can someone explain what is wrong here, and how the syntax must be given. I see the error thrown is "struct 1" has no member named var1
NOTE: The compiler I am using is not a C11, so this type of unnamed structure/union should be avoided.

I am kind of out of ideas here, I have never heard about this compiler, cannot find anything about it online. So, my last idea, is the following: name the union as well:
#include <stdio.h>
typedef struct {
union {
struct {
int a;
double b;
} var1;
struct {
int c;
double d;
} var2;
} uni;
} name_to_struct1;
int main(int argc, char* argv[]) {
name_to_struct1 asd;
asd.uni.var1.a = 1;
printf("%d\n", asd.uni.var1.a);
return 0;
}
If unnamed structs and unions are not allowed, maybe this could help.

Related

Reaching named struct in Unnamed union in C

I have the following structure of union and structs
union ab {
struct {
int a;
} a_st;
struct {
int b;
} b_st;
};
typedef struct c {
union ab;
} c_st;
when trying to "reach" the union elements directly:
c_st c;
printf("%d\n", c.a_st.a);
the following compilation error raised:
error: 'c_st' {aka 'struct c'} has no member named 'a_st'
if I provide the union name inside of the 'c_st' struct (e.g. ab_un), it works, but then I need to call c.ab_un.a_st.a, which is less desired.
is it necessary evil or have I missed something here?
Thanks in advance
Per this answer, the solution for gcc is to compile with -fms-extensions.
Here is an example. Tested with Visual C++ and MSYS2 gcc 10.2.
With this version of gcc, the -fms-extensions seems to be implied, and I get an error as mentionned in the comments if I compile instead with -fno-ms-extensions.
#include <stdio.h>
union ab {
struct {
int a;
} a_st;
struct {
int b;
} b_st;
};
typedef struct d {
union ab;
struct {
int c;
} c_st;
} d_st;
int main(void) {
d_st x;
printf("%zu\n", sizeof(d_st));
x.a_st.a = 1;
x.b_st.b = 2;
x.c_st.c = 3;
printf("a_st = %d\n", x.a_st.a);
printf("b_st = %d\n", x.b_st.b);
printf("c_st = %d\n", x.c_st.c);
return 0;
}
As an extension MSVC compiler (see Microsoft Specific Anonymous Structures) and gcc compiler with -fms-extensions (see gcc docs unnamed fields) support the syntax of unnamed structures. When using this extension it allows the code to compiler and access the unnamed structure members as if they were members of the containing structure.
If using this extension, the code will compile and access is fine, you just made a typo c_st should be d_st.
#include <stdio.h>
union ab {
struct {
int a;
} a_st;
struct {
int b;
} b_st;
};
typedef struct d {
union ab;
} d_st;
int main(void) {
d_st c;
printf("%d\n", c.a_st.a);
}
Without using this extension, the code will not compile, as explained below.
is it necessary evil or have I missed something here?
I would say it's just evil. The problem is with the following part:
struct c {
union ab;
};
It's the same as writing:
struct c {
};
You can put any type and follow it with a ;, like:
struct d {
int; float; unsigned long long; FILE *; some_other_type;
};
union ab is just a type. The some_type ; doesn't declare anything, nothing happens. The language grammar just allows you to write just a type as an expression without an identifier (ie. it's used in function declaration like void func(char*, int)), but nothing happens and such expression has no meaning. Your struct c is just empty, it has no members, it's undefined behavior.
trying to "reach" the union elements directly:
You can't access them, because they don't exists. There are no elements inside struct c - it's empty.
You may duplicate code (possibly with a macro):
struct c {
union { // anonymous union
struct {
int a;
} a_st;
struct {
int b;
} b_st;
};
};
and access via:
struct c C;
printf("%d\n", C.a_st.a);

Can you type alias an existing user-defined type in C?

Say I want to define two structs, the first one has a type, and the other I want to be of the same type as the first. Is this possible in C99?
Example:
typedef struct {
fieldA;
fieldB;
} typeA;
struct B {
fieldA
fieldB
};
typedef B A;
If not typedef, is there another keyword/way to do this?
Edit: It seems I wasn't being as clear as possible, judging from the feedback so far (which I greatly appreciate!)
My specific scenario is a typedef struct definition that is required to type alias another struct.
Yes of course! It's just like:
#include <stdio.h>
typedef int value_t;
typedef value_t data_t;
int main()
{
data_t i = 1;
printf("%d\n", i);
return 0;
}
You can typedef as many times as you like.

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.

c structures that contain function pointers

I declare all my structures using the following macro..
#define structure typedef struct
with this I declare a structure , for example
structure
{
int foo;
int(*proc)(void*);
}
_myobject;
the member proc , really received the argument which is a pointer
to the structure it belongs to ..
e.g.
myobj.proc(&myobj);
My question is , how can I declare the member proc with the type being
passed to it as a structure , and not a void * .. I know it doesn't make
a difference, this is only for aesthetics, as I have spent a lot of time
keeping my code clean..
structure
{
int foo
int(*foo)(_myobject*);
}
_myobject;
produces:
error: expected ':', ',', ';', '}' or '__attribute__' before 'int'|
You're attempting to refer to your struct recursively, which doesn't play nice with typedefs. One of the following should do:
typedef struct _myobject _myobject;
struct _myobject {
int foo;
int (*proc)(_myobject*);
};
...
typedef struct _myobject {
int foo;
int (*proc)(struct _myobject*);
} _myobject;
edit: If you want to continue using structure as much as possible (though really, other than for consistency with the existing code, I'm not sure why you would want to), you could do:
structure _myobject _myobject;
struct _myobject {
int foo;
int (*proc)(_myobject*);
};
...
structure _myobject {
int foo;
int (*proc)(struct _myobject*);
} _myobject;
Though both of these will require use of the struct identifier, if you wanted to avoid that.
You can change the macro a little:
#define structure(x,y) typedef struct x y x
structure (_myobject,
{
int foo;
int(*proc)(struct _myobject*);
}
);
which looks bad to me. Another way to do this is:
#define structure typedef struct
structure _myobject
{
int foo;
int(*proc)(struct _myobject*);
}
_myobject;

Why can't we typedef an (unnamed) structure twice at file scope, but we can typedef "int" twice without error?

The following code compiles and runs fine:
#include <stdio.h>
typedef int Someint;
typedef int Someint;
int main()
{
Someint b = 4;
printf("%d", b);
return 0;
}
The following code doesn't compile. It's giving me an error conflicting types for 'Somestruct'.
#include <stdio.h>
typedef struct
{
int x;
}
Somestruct;
typedef struct
{
int x;
}
Somestruct;
int main()
{
Somestruct b;
b.x = 4;
printf("%d", b.x);
return 0;
}
Why can I typedef one type (int in first code) twice without error ,but the same thing fails for another type (the structure above)? What is the difference between the two cases?
I'm using the MinGW compiler that came with CodeBlocks 12.11.
The thing is that when you do:
typedef struct
{
} Somestruct;
It creates an anonymous struct - you can expect some hidden implementation-defined guaranteed-unique placeholder identifier to be used - for which you specify the typedef. So, when you do it twice you get a conflict in having the same typedef-ed name asked to refer to two distinct structures. With int, you're simply repeating the original. If you give the struct an actual name then that lets you repeat the typedef:
typedef struct Somestruct
{
} Somestruct;
Because you're defining your typedef using an anonymous struct, both definitions are distinct.
The following doesn't do this, and works. (note that you can still only define the struct once)
#include <stdio.h>
typedef struct foo
{
int x;
}
Somestruct;
typedef struct foo Somestruct;

Resources