In gcc it is possible to create an anonymous struct, like this:
struct test2 {
struct {
int x;
int y;
};
int z;
};
But when I try to do the same thing with a pre-defined version of the anonymous struct, it fails:
struct test1 {
int x;
int y;
};
struct test2 {
struct test1;
int z;
};
The reason I want to do this is that I want to define a struct which contains a set of function pointers corresponding to "member functions" of a C class. If I don't include the struct anonymously, then I wind up having to do something obnoxious like this:
object->API->function(object,...);
which just plain doesn't work for some things I need to do (for instance, since "object.API" doesn't match "object", it makes it difficult or impossible to do automatic bindings from other languages which support hiding of the object pointer.)
At the moment, I just copy/paste the functions, but this is tedious and error prone. I could use the C pre-processor, but it seems just ugly to create a macro which has a bunch of function prototypes in it.
struct test1 is the name of the type of the struct. You are lacking a name for the field (and you cannot have "anonymous" fields other than inline-defined structs or unions).
struct test2 {
struct test1 myStructTest1;
int z;
};
EDIT: Apparently there's a GCC extension that allows you do that: -fms-extensions
Unless -fms-extensions is used, the unnamed field must be a structure or union definition without a tag (for example, struct { int a; };'). If -fms-extensions is used, the field may also be a definition with a tag such asstruct foo { int a; };', a reference to a previously defined structure or union such as `struct foo;', or a reference to a typedef name for a previously defined structure or union type.
struct s1 { int a; };
struct s2 { struct s1; };
Related
How can I typedef a struct but still keep the new type namespaced under the keyword 'struct'?
example:
struct foo {
int x;
};
typedef struct foo struct bar;
int main(void) {
struct bar bar;
bar.x = 10;
return 0;
}
but this doesn't work obviously.
Here are the errors if anyone is curious:
main.c:5:20: error: two or more data types in declaration specifiers
typedef struct foo struct bar;
^
main.c:5:27: warning: useless storage class specifier in empty declaration
typedef struct foo struct bar;
^
main.c: In function 'main':
main.c:9:13: error: storage size of 'bar' isn't known
struct bar bar;
How can I typedef a struct but still keep the new type namespaced under the keyword 'struct'?
So, it seems that you want to define a structure alias for another structure type.
This is not possible with typedef as it creates a single word alias. The new alias can't be consisted of multiple white space separated words.
But you can use a single name like struct_bar with struct implemented inside of the name to show that bar is a structure.
#include <stdio.h>
struct foo {
int x;
};
typedef struct foo struct_bar;
int main(void) {
struct_bar bar;
bar.x = 10;
return 0;
}
How can I typedef a struct but still keep the new type namespaced under the keyword 'struct'?.
You cannot. A namespace is a declarative region that provides a scope to the identifiers (names of the types, function, variables etc) inside it. The concept of Namespace as it is defined within C++, is not inherent in C.
So, if you are okay with minor changes in your requirements, instead of doing something unnatural, use a simple typedef:
Instead of this:
struct foo {
int x;
};
do this:
typedef struct {
int x;
}foo;
Then this will work:
typedef foo bar;
int main(void )
{
bar b;
b.x = 10;
return 0;
}
Note: Although namespaces are not inherent in in C, as they are in C++, there are some interpretations eg: as discussed here, that argue the point.
C doesn't have any type of support for namespaces (at least not in the sense that C++ does).
When you create a typedef, the new type name is a single identifier, not multiple words. So struct bar can't be an alias for another type. You would have to call it bar or some other one-word name.
You can't. This isn't how it works.
You cannot "create" a type whose name is more than one word, nor can you refer to a type alias using the keyword struct.
The purpose of writing struct, in this context, is to refer to a struct type by a name that wasn't introduced as an alias. The keyword is there to say that that's what you want to do. But it's not part of the name; it cannot be part of the name.
Fortunately, there's no reason to need or even want this.
I found a solution that works for cygwin:
struct foo {
int x;
};
struct bar {
struct foo;
};
I've the question about typedef statement.
Here is the code how i always write this statement:
typedef struct name
{
}name_t;
And here is the another example how i can write that:
typedef struct
{
}name;
Question is: what is purpose of that ways?
You need to use the first format if you have to refer to the type before the typedef is completed. This is necessary if the structure contains a pointer to the same type. This comes up when defining linked lists.
typedef struct name
{
int value;
struct name *next;
}name_t
You can't use name_t *next; inside the structure declaraction, because name_t isn't defined until later.
typedef struct name
{
}name_t;
name here is a struct tag and superfluous for the normal use-case, since you end up with a typedef anyhow and should only use name_t in your code from there on.
The only reason you'd add a tag there is the special case where you need a self-referencing struct such as a struct name* next; member in a linked list or such. In such cases we have to use the struct tag since the typedef name cannot be used before the typedef statement itself is done. Another alternative to that is to forward declare the struct.
The _t naming is industry standard way of naming types since the dawn of time. Unfortunately, the POSIX standard had the misguided idea to disallow such naming, so if you care about POSIX compliance, you should not name your types with _t in the end. If you don't care about POSIX, you should use _t because it gives proper, self-documenting code.
typedef struct name
{
int a;
double b;
char c;
}name_t;
name is a structure tag while name_t is a new type created by typedef.
To provide a structure tag explicitly is useful, if:
You want to implement a forward-declaration of the structure for use it in f.e. function definitions or other structures before the structure definition occurs (important if you have several translation units/C files).
For example:
File1.c
struct name; // forward declaration of structure `name`.
void foo(struct name *ptr)
{
....
}
struct bar
{
int x;
struct name y;
}
File2.c
typedef struct name
{
int a;
double b;
char c;
}name_t;
You want to define a pointer to an object of the structure itself inside of the structure, like required by linked lists:
typedef struct name
{
int a;
double b;
char c;
struct name *next;
}name_t;
This is a contrived example, but expresses the core problem. I have a union and a structure with the same nested structure from an existing code base:
typedef union _MyUnion
{
unsigned int A;
struct _MyNestedStruct
{
int field
} MyNestedStruct;
} MyUnion;
and
typedef struct _MyStruct
{
struct _MyNestedStruct
{
int field
} MyNestedStruct;
} MyStruct;
If I compile this under the Green Hills Compiler (GHC), then there are no problems. Compiling under GCC gives the error "error: redefinition of 'struct _MyStruct'".
First of all, why was I able to successfully compile with a named structure as a nested structure? I suspect that GHC is compiling with some C++ rules, or it supports named structures in a nested structure.
Second, what would allow me to successfully compile without any significant code changes? I know I can just delete the _MyNestedStruct from the nested structure, but does this have any consequences?
In C there are no namespace scopes, implicit or explict, so all the structure names share the same name space. Hence, struct _MyNestedStruct is defined twice and it is an error. GCC is correct, GHC is not.
If it were C++, then the code would be correct, because each struct would create a different namespace scope and so there is no name clash.
Solutions that I can think of:
A) If the structures are actually the same, define it just once outside of the other ones (you could have it inside the first one, but that would be weird).
struct _MyNestedStruct
{
int field
};
typedef union _MyUnion
{
unsigned int A;
struct _MyNestedStruct MyNestedStruct;
} MyUnion;
typedef struct _MyStruct
{
struct _MyNestedStruct MyNestedStruct;
} MyStruct;
B) Name the two structures differntly. In C the name is not so important, as long the definition is identical.
C) Use nameless structures. I reckon you will not be using these names at all:
typedef union _MyUnion
{
unsigned int A;
struct
{
int field;
} MyNestedStruct;
} MyUnion;
typedef struct _MyStruct
{
struct
{
int field;
} MyNestedStruct;
} MyStruct;
BTW, remember that any name beginning with and underscore plus an uppercase is reserved for the implementation and should not be defined by the user.
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;
...
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;