C11 anonymous structs via typedefs? - c

Anonymous structs have been added in the C11 standard, so
typedef struct {
struct {int a, b};
int c;
} abc_struct;
is valid and standard. Is it also within the standard to use a typedef in place of the full struct declaration? E.g.:
typedef struct {
int a, b;
} ab_struct;
typedef struct {
ab_struct;
int c;
} abc_struct;
The GCC documentation says that this is a Plan 9 extension, but then it works in the
few compilers I've tried (including GCC...). By my reading of the standard itself,
I think it's OK, but this is the sort of close reading that's easy to screw up.

This was apparently asked in a question to the C committee by Joseph S. Myers of the gcc team. And the answer is no, it is not valid in C11.
See the answer here:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1549.pdf
And Myers's comment:
This week's London WG14 meeting agreed to disallow the use of typedefs in declaring anonymous structure and union fields, as per N1549.
source http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01151.html
The question was asked in SC22WG15.12205 see 5.28 SC22WG14.12205, Anonymous Structures (N1425) in http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1490.pdf

Actually your second snippet is fraught with peril and is not equivalent to the first one without explicitly specifying -fplan9-extensions in gcc.
In particular ab_struct; declaration on line 6 does NOTHING (as per gcc warning). Just pasting your second snippet in foo.c generates:
foo.c:6: warning: declaration does not declare anything
And in particular if you were to try:
typedef struct {
int a, b;
} ab_struct;
typedef struct {
ab_struct;
int c;
} abc_struct;
int main() {
abc_struct abc;
abc.a = 5;
return 0;
}
you would get a syntax error on line 13 abc.a = 5; without the -fplan9-extensio.
whereas using the top snippet your anonymous structure will work as you are thinking it should. Namely:
typedef struct {
struct {
int a, b;
};
int c;
} abc_struct;
int main() {
abc_struct abc;
abc.a = 5;
return 0;
}

Well, I'm afraid I haven't bothered to get the finished standard yet, but here's what the final draft says:
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.
I can only interpret the as that only struct {}; and union {}; can be an anonymous struct/union.

Related

Type of a struct member at compile time

Is there a way of knowing the type of a struct member at compile time? Something analogous to offsetof(), but for types.
Eg. something like:
typedef struct{
int b;
char c;
}a_t;
typeof(a_t,b) a_get_b(void* data){
return *(typeof(a_t,b)*)(data + offsetof(a_t,b));
}
If you're willing to use typeof (which is currently a very common nonstandard C extension slated for inclusion in the next version of the standard), you can apply it to a member obtained from a compound literal as in typeof((a_t){0}.b):
typedef struct{ int b; char c; }a_t;
typeof((a_t){0}.b) a_get_b(void* data){ return (a_t*){data}->b; }
(Given a type a_t, (a_t){0} is a reliable way to get an instance of it. Because of how initialization works in C, the 0 will initialize a deepest first elementary member and elementary types are scalars and therefore 0-initializable.)
As for the obtaining the member from a void pointer pointing to the container, you could do:
*(typeof(&(a_t){0}.b)((char*)data + offsetof(a_t,b))
but that's just an awfully long-winded way to do:
(a_t*){data}->b
(which is 100% equivalent to the former as long as the effective type of data is indeed a_t*).
Another way it works:
#include <stdio.h>
#define typeof_element(_struct,el) typeof(((_struct *)(0))->el)
typedef struct{
int a;
int b;
}Row;
int main()
{
typeof_element(Row, a) value_a = 10;
printf("%d\n", value_a);
return 0;
}
Another way (other than Jerry Jeremiah's) is:
#define struct_get(STRUCT,ELEM) *(typeof(STRUCT.ELEM)*) (STRUCT+offsetof(typeof(STRUCT),ELEM))

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

My dev++ is returning non-static warning. Whats the problem with the code?

I'm doing this code and can't find a way to compile. Tried Online compilers which each one of them gives a different reason for the error, my Dev++ says that
[Warning] non-static data member initializers only available with -std=c++11 or -std=gnu++11
Every online compiler and cant find an error on code either
#include <stdio.h>
#include <stdlib.h>
struct uninter
{
char nome[5] = {'L','U','C','A','S'};
int RU = 2613496;
}; struct uninter aluno;
int main() {
int i;
printf("\n Nome do Aluno: ");
for (i = 0; i < 5; i++ ){
printf( "%c\n", aluno.nome[i]);
}
printf("\n RU do aluno: %d \n ", aluno.RU);
system("pause");
return 0;
}
[Warning] non-static data member initializers only available with -std=c++11 or -std=gnu++11
The warning message you are receiving is because you are compiling your code with a C++ compiler. Probably with with -std=c++98 or -ansi or otherwise implicitly using the 1998 standard.
You are trying to create a default initializer for a member of a struct, which is a feature not added to C++ until the 2011 standard. To compile a C++ program with this feature without the compiler warning you about this, you need to pass in the -std=c++11 or -std=gnu++11 flags to the compiler command as the warning states.
If this is expected to be C code rather than C++ code, default initializers for structs are simply not a part of the language. You can initialize its member variables upon declaration of an object of that struct's type.
An example of how you might do this with a C compiler:
// definition of the struct
struct uninter
{
char nome[5];
int RU;
};
// declaration of an instance of an object of type struct uninter
struct uninter x = {{'L','U','C','A','S'}, 2613496};
// alternative declaration if using C99 standard with designated initializers
struct uninter y = {
.nome={'L','U','C','A','S'},
.RU= 2613496
};
in general, cannot initialize a struct contents in C in the definition of the struct. Suggest something similar to:
struct uninter
{
char nome[5];
int RU;
};
struct uninter aluno = {.nome = "LUCAS", .RU = 2613496};
The problem with the code is that it is using non-static data member intializers:
struct uninter
{
char nome[5] = {'L','U','C','A','S'};
int RU = 2613496;
}; struct uninter aluno;
... which is a C++11 feature, and therefore isn't portable unless you are using a C++11 (or later) compiler. (It might still compile under older compilers, if they have that feature enabled as a compiler-specific extension, but they are politely warning you that you can't expect it to compile everywhere)
If you don't want your program to require C++11 or later to compile, the easiest thing to do would be to rewrite it so that the struct's member variables are initialized via a different mechanism. For example (assuming your c tag is intentional) you could have an init-method do it for you:
struct uninter
{
char nome[5+1]; // +1 for the NUL/terminator byte!
int RU;
}; struct uninter aluno;
void Init_uninter(uninter * u)
{
strcpy(u->nome, "LUCAS");
u->RU = 2613496;
}
[...]
int main() {
int i;
Init_uninter(&aluno);
[...]
... or if you actually intended to specify/use a pre-C++11 version of C++, a default-constructor would do the trick a bit more gracefully:
struct uninter
{
uninter()
{
strcpy(nome, "LUCAS");
RU = 2613496;
}
char nome[5+1]; // +1 for the NUL terminator byte!
int RU;
}; struct uninter aluno;

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.

Using structure in C and C++

I am new to C and I want to know how to access elements inside a structure which is placed inside a structure.
struct profile_t
{
unsigned char length;
unsigned char type;
unsigned char *data;
};
typedef struct profile_datagram_t
{
unsigned char src[4];
unsigned char dst[4];
unsigned char ver;
unsigned char n;
struct profile_t profiles[MAXPROFILES];
} header;
How to access elements inside profile_t??
struct profile_t;
The above statement doesn't create an object of type profile_t. What you need to do is -
struct profile_t inObj ;
Then create object for profile_datagram_t. i.e.,
header outObj ; // header typedef for profile_datagram_t
Now you can access elements like -
outObj.inObj.type = 'a' ; // As an example
In C++, while creation of object for a structure, struct key word isn't necessary.
On your question edit and comment :
struct profile_t profiles[MAXPROFILES];
profiles is an array of objects of type profile_t. To access the individual object, just use the [] operator. i.e.,
header obj ;
obj.profiles[0].type = 'a' ; // Example
obj.profiles[i], where i can take values from 0 to MAXPROFILES - 1, gives the object at index i.
Not sure what happends in C, but in C++, rest of the stuff aside, the following declares two types.
struct profile_datagram_t
{
struct profile_t;
};
One type is named profile_datagram_t and the other is called profile_datagram_t::profile_t. The inner type declaration is just a forward declaration, so you'll need to define the type after.
struct profile_datagram_t::profile_t
{
// ...
};
Then, you can use the struct as follows:
int main ( int, char ** )
{
profile_datagram_t::profile_t profile;
}
Some compilers support a nonstandard extension to the C language (that I actually rather like, despite it being nonstandard) called anonymous structs (or unions). Code demonstration:
struct x {
int i;
};
struct y {
struct x;
};
int main(void)
{
struct y;
y.i = 1; // this accesses member i of the struct x nested in struct y
return 0;
}
In a nutshell, if you don't give the struct (or union) member a name, you can access its members directly from the containing struct (or union). This is useful in situations where you might have given it the name _, and had to do y._.i - the anonymous struct syntax is much simpler. However, it does mean that you have to remember the names of all members of both structs and ensure they never clash.
This is all, of course, a nonstandard extension, and should be used with caution. I believe it works on MSVC and can be enabled in GCC with a switch. Don't know about any other compilers. If you're worried about portability, give the member a proper name.
EDIT: According to the GCC reference (below) this behavior is being added to the upcoming C1X standard, so it won't be nonstandard for long. I doubt MSVC will support C1X since they refuse to support C99 as it is, but at least this feature is becoming part of the standard.
However, the behavior shown above is MSVC only. The C1X (and GCC without the -fms-extensions switch) syntax doesn't allow the unnamed struct member to have a name:
struct y {
struct {
int i;
};
};
int main(void) {
struct y;
y.i = 1; // this accesses member i of the struct x nested in struct y
return 0;
}
References for various compilers (they have different names but are the same concept):
GCC (unnamed fields): http://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html'
MSVC (anonymous structs): http://msdn.microsoft.com/en-us/library/z2cx9y4f.aspx
Basically you can use the following format:
variable = profile_t.element
profile_t.element = ?
EDIT: In your declaration of profile_datagram_t, the proper definition for struct profile_t should be:
struct profile_t someProfile;
Let's say you have:
header profileDiagram1;
struct profile_t profile1;
profileDiagram1.someProfile = profile1;
To access length, type or *data from profile_t:
profileDiagram1.someProfile.type;
profileDiagram1.someProfile.length;
...

Resources