What is wrong with this structure/union declaration? - c

I declared this structure in global scope,
struct a{
int a;
int x;
union b{
int a;
int b;
int y;
};
};
And then declared an union inside main,
union b a;
And this is not giving any errors. But if declare union 'a' in the definition of structure, like:
struct a{
int a;
int x;
union b{
int a;
int b;
int y;
}a;
};
It gives error "duplicate member a". (WE USED THE SAME NAME 'a' IN THE PREVIOUS CASE)
Why does one work and another does not?
Secondly, how can we use the union declared inside struct, independently, but can't use any other integer variable, say 'x'?
Like, i can perform the following successfully:
union b z; //works in this case, BUT not if we declare 'z' with the definition.
z.y=6; //works
x=6; //gives error
(i understand we are declaring union inside main, but its definition in inside the struct. Like, struct.union.union_variable makes sense, but having union.union_variable directly make it kind of independent. Shouldn't it be treated like 'x'?)

It gives error "duplicate member a". (WE USED THE SAME NAME 'a' IN THE PREVIOUS CASE) Why does one work and another does not?
Because your struct has now two members named a: first one is an int and second one is of type b (your union). You wouldn't be surprised to see this doesn't compile:
struct a {
int a;
float a;
};
In your case you have exactly same situation, imaging you defined b outside struct and you try to use it like this:
struct a {
int a;
union b a;
};
Secondly, how can we use the union declared inside struct, independently, but can't use any other integer variable, say 'x'? Like, i can perform the following successfully:
Where is x declared? You don't have any local variable named x (what you may have is a struct member named x but then you need such structure). One of following (according to what you're trying to do):
int x = 6;
struct a w;
a.x = 6;

Related

Why must a struct member always have an identifier?

Why must a struct member always have an Identifier? The answer of course is because that is how the language is defined, but I'd like to understand the reason behind it.
typedef union {
int a;
struct {
int a; //Why is an identifier necessary here?
int b;
} s;
} u;
There are grammar complications here. Consider int a, b, c;. That declares three objects. int a, b; declares two, and int a; declares one. So how many should int; declare? When a declaration with no declarator appears in other contexts, it does not declare any object. For example, struct foo { int x; }; defines the type struct foo, but it does not declare an object of that type.
We could make an exception for declarations in structures, and say that, if they have no declarators, then they declare one unnamed member. But then we are introducing another special case in to the grammar. Then struct foo { int x; };, which has no declarator, would declare a member object of type struct foo when it appears inside a structure definition, but it would not declare any object when it appears outside of a structure definition.
So this adds complications to the language. And it is not necessary; somebody who wants a member in a structure can always give it a name and can choose a name that will not interfere with other code.
Actually, bit field members do not need a name, at least according to gcc -std=c99 -Wall -Wextra -pedantic, which gives no warning when compiling this code:
struct Foo
{
char x;
unsigned :8;
};
If you really don't want to have an identifier for a member that isn't a bit-field, you can name it something like _reserved0 to explicitly show that this is just reserved space that you don't want to access from your code.
I don't know the opinions of the people who wrote the C standard. Maybe they were thinking a struct member without a name was almost always a bug (i.e. the programmer forgot the name), and they wanted to help people catch those bugs, but they made a few exceptions to the rule.
//Why is an identifier necessary here?
This a is distinct from the a outside the structure. The compiler needs to know which one you want to access
If you use distinct names you can use anonymous structure in your union
typedef union {
int a;
struct {
int b;
int c;
};
} u;
u foo(int x, int y, int z)
{
u un;
u.a = x;
u.b = y;
u.c = z;
}

Why does declaring a structure within a structure not work?

Learning C recently and came across this problem
struct myStruct {
int a;
float b;
struct thisStruct c;
};
struct thisstruct {
int d;
float e;
struct myStruct c;
};
'struct thisStruct c;' returns an error, but not 'struct myStruct c;'. Why is this so?
For starters there is a typo in the presented code snippet.
struct myStruct {
int a;
float b;
struct thisStruct c;
};
struct thisstruct {
int d;
float e;
struct myStruct c;
};
It seems you mean that the second declaration declares a structure with the name thisStruct instead of the name thisstruct.
As for your question then according to the C Standard (6.7.2.1 Structure and union specifiers)
3 A structure or union shall not contain a member with incomplete or
function type (hence, a structure shall not contain an instance of
itself, but may contain a pointer to an instance of itself), except
that the last member of a structure with more than one named member
may have incomplete array type; such a structure (and any union
containing, possibly recursively, a member that is such a structure)
shall not be a member of a structure or an element of an array
In this structure declaration
struct myStruct {
int a;
float b;
struct thisStruct c;
};
the type struct thisStruct is an incomplete type. Its size is unknown. You may declare a pointer of this structure type like
struct myStruct {
int a;
float b;
struct thisStruct *c;
};
because pointer types are always complete types. Their sizes are known.
Otherwise in these declarations
struct myStruct {
int a;
float b;
struct thisStruct c;
};
struct thisStruct {
int d;
float e;
struct myStruct c;
};
you have an infinite recursion. That is the definition of the data member
struct thisStruct c;
includes the definition of the structure thisStruct that in turn again includes the definition of the structure myStruct and so on.
This C code too, like every other C code, can be regarded as parsed from top to bottom. Therefore at the point where you declare struct thisStruct c, the compiler has no idea what that type is, because it has not yet seen that struct definition.
You could declare pointers to structs before the compiler knows what those structs are, by forward declaring the struct:
struct thisStruct;
struct myStruct {
int a;
float b;
struct thisStruct* c;
};
However, this means you have to use pointers.
That being said, a program design of some X containing an Y containing an X is very likely nonsense. I very much doubt there exists a valid scenario where you would need that. Reconsider your design.
As the C compiler does not know the size of the struct or union which was not yet declared it cant place such a struct or union inside other data structure. Only pointer (as size of pointer is known to the compiler) to not yet declared structure or union can be used.

C: Avoid indirection to refer to fields of struct inside struct [duplicate]

If I have these structures:
typedef struct { int x; } foo;
typedef struct { foo f; } bar;
Normally you would access x through b.f.x, but is there a way to set this up so that you can access element x without referring to f?
bar b;
b.x = ...
My first intuition is that you can't since there would be a possibility for name conflicts if two sub structures both had a member x and I can't figure out what the compile error would be. However, I recall working in some frameworks where this was possible.
In C++ I worked in a framework once where bar existed, and you could access its members as member variables this->x from a different class. I'm trying to figure out how that could be done.
You can with C11:
§ 6.7.2.1 -- 11
An unnamed member whose type specifier is a structure specifier with no tag is called an
anonymous structure; an unnamed member whose type specifier is a union specifier with
no tag is called an anonymous union. The members of an anonymous structure or union
are considered to be members of the containing structure or union. This applies
recursively if the containing structure or union is also anonymous.
So this code might work:
#include <stdio.h>
typedef struct { int x; } foo;
typedef struct { foo; } bar;
int main(void)
{
bar b;
b.x = 1;
printf("%d\n", b.x);
}
The problem here is that different compilers disagree in my tests on whether a typedef is acceptable as a struct specifier with no tag The standard specifies:
§ 6.7.8 -- 3
In a declaration whose storage-class specifier is typedef, each declarator defines an
identifier to be a typedef name that denotes the type specified for the identifier in the way
described in 6.7.6. [...] A typedef declaration does not introduce a new type, only a
synonym for the type so specified.
(emphasis mine) -- But does synonym also mean a typdef-name specifier is exchangeable for a struct specifier? gcc accepts this, clang doesn't.
Of course, there's no way to express the whole member of type foo with these declarations, you sacrifice your named member f.
Concerning your doubt about name collisions, this is what gcc has to say when you put another int x inside bar:
structinherit.c:4:27: error: duplicate member 'x'
typedef struct { foo; int x; } bar;
^
To avoid ambiguity, you can just repeat the struct, possibly #defined as a macro, but of course, this looks a bit ugly:
#include <stdio.h>
typedef struct { int x; } foo;
typedef struct { struct { int x; }; } bar;
int main(void)
{
bar b;
b.x = 1;
printf("%d\n", b.x);
}
But any conforming compiler should accept this code, so stick to this version.
<opinion>This is a pity, I like the syntax accepted by gcc much better, but as the wording of the standard doesn't make it explicit to allow this, the only safe bet is to assume it's forbidden, so clang is not to blame here...</opinion>
If you want to refer to x by either b.x or b.f.x, you can use an additional anonymous union like this:
#include <stdio.h>
typedef struct { int x; } foo;
typedef struct {
union { struct { int x; }; foo f; };
} bar;
int main(void)
{
bar b;
b.f.x = 2;
b.x = 1;
printf("%d\n", b.f.x); // <-- guaranteed to print 1
}
This will not cause aliasing issues because of
§ 6.5.2.3 -- 6
One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the completed type of the union is visible. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members
C: Highly unrecommended, but doable:
#include <stdio.h>
#define BAR_STRUCT struct { int x; }
typedef BAR_STRUCT bar;
typedef struct {
union {
bar b;
BAR_STRUCT;
};
} foo;
int main() {
foo f;
f.x = 989898;
printf("%d %d", f.b.x, f.x);
return 0;
}
Anonymous structs are a widly-spread extension in standards before C11.
C++:
The same as in C, you can do here but anonymous structs are not part of any C++ standard, but an extension.
Better use inheritance, or do not use this shortcut at all.
Of course, do not use something like #define x b.x)).
In C you can't access members of members like this.
You can however access members of an anonymous inner struct:
struct bar {
struct {
int x;
}
};
...
struct bar b;
b.x = 1;
In C++ you use inheritance:
struct foo {
int x;
};
struct bar: public foo {
};
...
struct bar b;
b.x = 1;
In C (99 and onward) you can access the common initial sub-sequence of union members, even if they weren't the last member written to1.
In C11, you can have anonymous union members. So:
typedef struct { int x; } foo;
typedef struct {
union {
foo f;
int x;
};
} bar;
Yes, that applies to structures. But according to the standard:
A structure pointer, suitably converted, points to the first member.
A union pointer, suitably converted, points to any union member.
So their location in memory is the same.
This is not possible in C. In C++ however you can use inheritance which is probably what you were thinking about.
In C++, you can use inheritance and member name conflicts are sort of resolvable with :: and treating the base classes as members.
struct foo { int x; };
struct bar : foo { };
struct foo1 { int x; };
struct bar1 : foo1 { char const* x; };
bar b;
bar1 b1;
int main()
{
return b.x + b1.foo1::x;
}
In standard C, it's impossible, however several compilers (gcc, clang, tinycc) support a similar thing as an extension (usually accessible with -fms-extensions (on gcc also with -fplan9-extensions which is a superset of -fms-extensions)), which allows you to do:
struct foo { int x; };
struct bar { struct foo; };
struct bar b = { 42 };
int main()
{
return b.x;
}
However, there's no resolution for conflicting member names with it, AFAIK.
In C++, it is possible in two ways. The first is to use inheritence. The second is for bar to contain a reference member named x (int &x), and constructors that initialise x to refer to f.x.
In C, it is not possible.
Since the C standard guarantees that there isn't padding before the first member of a struct, there isn't padding before the foo in bar, and there isn't padding before the x in foo. So, a raw memory access to the start of bar will access bar::foo::x.
You could do something like this:
#include <stdio.h>
#include <stdlib.h>
typedef struct _foo
{
int x;
} foo;
typedef struct _bar
{
foo f;
} bar;
int main()
{
bar b;
int val = 10;
// Setting the value:
memcpy(&b, &val, sizeof(int));
printf("%d\n", b.f.x);
b.f.x = 100;
// Reading the value:
memcpy(&val, &b, sizeof(int));
printf("%d\n", val);
return 0;
}
As others have noted, C++ offers a more elegant way of doing this through inheritance.

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;

Structs that refer to each other

I want to have two structs that can contain each other. Here is an example:
struct a {
struct b bb;
};
struct b {
struct a aa;
};
But this code doesn't compile. gcc says:
test.c:3: error: field ‘bb’ has incomplete type
Is there a way to achieve this?
How is that supposed to work? a would contain b, which would contain a, which would contain b, etc...
I suppose you want to use a pointer instead?
struct b;
struct a {
struct b *bb;
};
struct b {
struct a *aa;
};
Even that though is bad coding style - circular dependencies should be avoided if possible.
struct a;
struct b;
struct a{
struct b *bb;
};
struct b{
struct a *aa;
};
Most of the header file declare the structure before defining its members. Structure definition will be defined in somewhere else.
The usual way of dealing with this is to make them pointers and then dynamically allocate them or even just assign the pointer from the address of a static instance of the other struct.
struct a {
struct b *bb;
};
struct b {
struct a *aa;
};
struct a a0;
struct b b0;
void f(void) {
a0.bb = &b0;
b0.aa = &a0;
}
I would suggest, however, that you look for a tree-structured organization. Perhaps both objects could point to a common third type.
This is nonsensical.
Imagine if you say that every X contains a Y and every Y contains an X, then inside each X is a Y which in turn contains an X, which in turn contains a Y, which in turn contains an X, ad infinitum.
Instead, you can have an X contain a reference to or (or pointer to) a Y and vice-versa.

Resources