I have the following structs:
typedef struct cxt_simple_socket_address_s
{
int is_ipv6;
cs_inaddr_t ip;
unsigned short ip_port;
} cxt_simple_socket_address_t;
typedef struct cs_inaddr
{
union {
struct in6_addr in6;
struct
{
uint8_t pad[12];
uint32_t in;
};
long long as_longs[2];
};
} cs_inaddr_t;
I would like to initialize a struct of type cxt_simple_socket_address_t upon declaration:
cxt_simple_socket_address_t any = {.in = INADDR_ANY};
This line doesn't compile. I have tried countless other variations, but I believe my problem is than .in is found within an anonymous struct inside an anonymous union.
HELP?
Firstly order of declaration is wrong.
struct cs_inaddr should be declared first, followed by struct cxt_simple_socket_address_s.
Since its is nested Structure (compiler will look for definition of cs_inaddr first).
typedef struct cs_inaddr
{
union {
struct in6_addr in6;
struct
{
unsigned char pad[12];
unsigned int in;
};
long long as_longs[2];
};
} cs_inaddr_t;
typedef struct cxt_simple_socket_address_s
{
int is_ipv6;
cs_inaddr_t ip;
unsigned short ip_port;
} cxt_simple_socket_address_t;
Initialization of variable should be as:
cxt_simple_socket_address_t any = {.ip = {.in = INADDR_ANY}};
Tested it using the below:
cxt_simple_socket_address_t any = {.ip = {.in = 100}};
printf("%d\n", any.ip.in);
Output: 100
Note:
The nested (inner) structure can be anonymous, since the outer structure has a tag name.
Hence can be accessed.
cxt_simple_socket_address_s doesn't contain any field naming in. Are you mean
cxt_simple_socket_address_t any = {ip.in = INADDR_ANY};
?
First of all you need to move the whole declaration of struct cs_inaddr before cxt_simple_socket_address_t in order to make it visible.
Then initialize using:
cxt_simple_socket_address_t any = {.ip.in = INADDR_ANY};
Also note that anonymous unions are introduced in C11 or as a gcc extension.
Related
Is there a way to access individual members of a structure that is nested inside two other structures without using the dot operator multiple times?
Unlike some variants of BASIC or Pascal that have a with keyword which allows you to access inner members of a structure directly, C has no such construct.
You can do this however with pointers. If you have a particular inner member you're going to access frequently, you can store the address of that member in a pointer and access the member through the pointer.
Suppose for example you had the following data structures:
struct inner2 {
int a;
char b;
float c;
};
struct inner1 {
struct inner2 in2;
int flag;
};
struct outer {
struct inner1 in1;
char *name;
};
And a variable of the outer type:
struct outer out;
Instead of accessing the members of the innermost struct like this:
out.in1.in2.a = 1;
out.in1.in2.b = 'x';
out.in1.in2.c = 3.14;
You declare a pointer of type struct inner2 and give it the address of out.in1.in2. Then you can work directly with that.
struct inner2 *in2ptr = &out.in1.in2;
in2ptr->a = 1;
in2ptr->b = 'x';
in2ptr->c = 3.14;
Is there a way to access individual members of a structure that is nested inside two other structures without using the dot operator multiple times?
No. Not via standard C.
To make the accessing code cleaner however, you might consider some static inline helper functions.
For example:
struct snap {
int memb;
};
struct bar {
struct snap sn;
};
struct foo {
struct bar b;
}
static inline int foo_get_memb(const struct foo *f)
{
return f->b.sn.memb;
}
Not completely answering your question.
The 1st member of any struct can be accessed by taking the struct's address, casting it to a pointer type pointing to the struct's 1st member and dereferencing it.
struct Foo
{
int i;
...
};
struct Foo foo = {1};
int i = *((int*) &foo); /* Sets i to 1. */
Adapting this to nested struct's gives us for example:
struct Foo0
{
struct Foo foo;
...
};
struct Foo1
{
struct Foo0 foo0;
...
};
struct Foo2
{
struct Foo1 foo1;
...
};
struct Foo2 foo2;
foo2.foo1.foo0.foo.i = 42;
int i = *((int*) &foo2); /* Initialises i to 42. */
struct Foo0 foo0 = {*((struct Foo*) &foo2)}; /* Initialises foo0 to f002.f001.foo0. */
This is well defined, as the C-Standard guarantees that there is no padding before a struct's 1st member. Still it's not nice.
You could use the -> operator.
You could take the address of an inner member and then access it via the pointer.
Is the following, at file scope, a type declaration or an unnamed variable?
struct student_s {
char* name;
int age;
double height;
struct student_s* next;
};
If it is a type definition, then what is the difference with:
typedef struct student_s {
char* name;
int age;
double height;
struct student_s* next;
};
?
(Background: see my answer at Changing a variable from global to local - C, where I believe the first introduces an unnamed variable that is then optimized away by the compiler.)
Note: the question has been flagged as a possible duplicate of In what scope is a struct member identifier put? but I believe I am not asking a question about the scope of the members but about what the declarations actually create. However. answers to Difference between 'struct' and 'typedef struct' in C++? do explain my question.
As per the C standard, a structure declaration in the form like
struct student_s {
char* name;
int age;
double height;
struct student_s* next;
};
is the declaration of a type. Quoting C11, chapter §6.7.2.1
The presence of a struct-declaration-list in a struct-or-union-specifier declares a new type, within a translation unit. The struct-declaration-list is a sequence of declarations for the members of the structure or union. [...]
C standard does not mandate creating a variable (either named or unnamed) for that type.
In your second snippet, you actually (try to) typedef to nothing. However, if you change your snippet to the form of
typedef struct {
//.....members
} student_s ;
you'll be creating a type student_s (typedef to an unnamed structure type) which you can use later.
FWIW, we never talked about a variable being created here, anyways. It's all about types.
First declaration declares a type. After that declaration, the type struct student_s is known, and you can declare variables of that type or pointer to it :
struct student_s student1;
struct student_s *pStudent;
The second declaration is weird even if is compiles. The common usage would be :
typedef struct {
char* name;
int age;
double height;
struct student_s* next;
} studend_t;
which declares an alias student_t to an anonymous struct. It can then be used directly :
student_t student1;
student_t *pStudent;
BUT THE SECOND EXAMPLE DOES COMPILE (even with a warning) AND IS THE SAME AS FIRST ONE !
What it really does is to declare a void alias to struct student_s. The typedef is ignored and produces a warning : typedef requires a name, but as a side effect, the struct is declared, exactly as it was in first example.
So the true answer to the actual question is THERE ARE NO DIFFERENCES except for a warning.
Both are type definitions. The second one is one incomplete. It doesn't supply a name as the the argument of typedef. Much better is to use
typedef struct student_s {
char* name;
int age;
double height;
struct student_s* next;
} student;
Regarding the legality of
typedef struct student_s {
char* name;
int age;
double height;
struct student_s* next;
};
I've asked that as a separate question, Legality of `typedef struct foo {int bar};`
It's a type, and you can't have an anonymous instance of a struct. For comparison, this declares both the type struct_type and an instance struct_instance of that type:
struct struct_type {
/* blah */
} struct_instance;
If you wanted to declare another instance in isolation (from the type decl) you'd use
struct struct_type another_instance;
The use of typedef - if done correctly, unlike your example - just allows you to give the type another name which doesn't require the struct keyword to declare an instance:
typedef struct_type MyStruct;
MyStruct yet_another_instance;
or equivalently
typedef struct struct_type {
/* blah */
} MyStruct;
omitting the name (struct_type) gives you an anonymous struct type which can only referred to by its typedef'd name.
Note 1
Since your original struct contains a next pointer to its own type, that type must have a name at the point the member is declared. So, you cannot declare an anonymous struct with a self-typed pointer. If you give your anonymous struct type a name with typedef, that name doesn't exist until after the member declaration, so can't be used there.
typedef struct /*S*/ {
struct S *next; /* T doesn't exist yet, so without S, you can't declare this */
} T;
Note 2
You can declare an anonymous instance of an anonymous union, as a member:
struct S {
union {
int i;
unsigned u;
};
};
struct S s;
s.i = -1;
printf("%x\n", s.u);
but that's a very special case. I took the remark about this out of the main argument, in case it was misleading.
struct A { ... }
creates struct 'A' visible in struct namespace (which has nothing common with C++ namespaces). So, to access struct you have to use struct keyword;
struct A a;
When defined with typedef struct
typedef struct A { ... } B;
becomes visible and bound to B, and you can easily create struct like common variable of type B
B a;
Please, correct me someone, if I am wrong.
The difference is that with the first example, you have to declare a new variable like this: struct student_s variable;, however with the second example, you may simply do student_s variable;.
struct one
{
int member;
};
struct two
{
int member;
} structure;
If I want to call the above structures in the main() function then in the first case do I need to name the struct one to any random name of my choice and then and then call its member like this:
int main() {
struct one random_name;
random_name.member = 1;
}
and in the second case I have already named the structure so it's just that I can directly call the member with the name structure like this:
int main() {
structure.member = 1;
}
Is the version below valid or do I have to put typedef in front of the struct?
struct {
int member;
} structure;
Using int as the type of the structure members throughout, then:
struct one
{
int member;
};
This is a perfectly fine definition of the type struct one. It defines no variables of type struct one; it is simply a type that can be used later in the translation unit.
struct two
{
int member;
} structure;
This is a perfectly fine definition of the type struct two and is also the definition of a variable structure of type struct two.
If I want to call the above structures in the main() function then in the first case do I need to name the struct one to any random name of my choice and then and then call its member like this:
int main(void)
{
struct one random_name;
random_name.member = 1;
}
If you want to use a variable of type struct one, you will have to define it, and the way you've done so is fine. You don't 'call' members of structures. You use them.
and in the second case I have already named the structure so it's just that I can directly call the member with the name structure like this:
int main(void)
{
structure.member = 1;
}
This is also valid because you defined the variable structure at the same time as you defined the type struct two.
Is the below version valid or do I have to put typedef in front of the struct:
struct
{
int member;
} structure;
This is also legitimate code. It defines an anonymous structure type and defines a single variable of that type. It is the only variable of that type that can exist, but occasionally it is useful to use this.
Note that if the last structure was followed by:
struct
{
int member;
} form;
the types of the variables form and structure are different; you cannot legitimately assign one to the other, for example, or pass either of them to another function, etc.
More typically, you either give the structure type a tag (struct three) or use a typedef (typedef struct { int member; } four;) or both (typedef struct five { int member; } five;, where it is legitimate to use the same name for the tag and the type name as I showed, though there is also an extensive tradition of using different names for the type and the tag).
So with typedef struct { int member; } structure;, in main() creating one or more variables of type structure is possible, like this?
structure first_var;
structure second_var;
This is entirely legitimate. You could instead write:
structure first_var, second_var;
though many people prefer one variable per declaration.
Whereas if we don't use typedef and just do struct { int member; }structure; then I have just got one variable with name structure and can use that only in main(), such as structure.member = 1; and can't create more.
More or less. You can write:
struct { int member; } var1, var2, … varN;
and now you have multiple variables all of the same type. However, although you can write:
struct { int member; } var1;
struct { int member; } var2;
the two variables var1 and var2 are not officially of the same type. There are complicated bits of wording in the standard in section 6.2.7 Compatible types and composite types which might let you off the hook, but GCC 4.9.1 set fussy says:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -c tagless.c
tagless.c: In function ‘main’:
tagless.c:13:10: error: incompatible types when assigning to type ‘struct <anonymous>’ from type ‘struct <anonymous>’
var1 = var2;
^
$
tagless.c
struct
{
int member;
} var1;
struct
{
int member;
} var2;
int main(void)
{
var1.member = 1;
var2.member = 2;
var1 = var2;
return 0;
}
two more doubts:::::::
Whereas if we don't use typedef and just do struct{int member;}structure;
then i just got one variable with name structure and can use that only in
main structure.member=1; and can't create more –
Ans : You can always create more than just one variable once you have declared the structure, so its not that if you dont use typedef you can have only one variable for your structure. For eg:
struct structure
{
int number;
};
int main()
{
structure var1, var2, var3; //...any number of variables can be declared here.
var1.number = 30;
var2.number = 45;
var3.number = 90;
printf("\nvar1 = %d, var2 = %d, var3 = %d\n", var1.number, var2.number, var3.number);
return 0;
}
For a better understanding of typedef,
Consider this example :
1.
struct structure
{
int number;
};
typedef struct structure structure;
2.
typedef struct structure
{
int number;
}structure;
---------------------
Both of the above declarations are equivalent.
typedef is used to define a new name for a variable or a keyword.
Suppose in case if your structure declaration is something like this :
struct this_is_my_structure
{
int number;
};
then every time you declare an instance of this structure you will have to use this long name in front of your instance, like:
int main()
{
struct this_is_my_structure var1; // you dont want to write such long types for variables
var1.number = 23;
return 0;
};
You will find typedef helpful here :
typedef struct this_is_my_structure structure;
Now every time you want to declare an instance of type "this_is_my_structure" all you have to do is the following :
int main()
{
structure var1;
var1.number = 23;
return 0;
}
I am using structs in my project in this way:
typedef struct
{
int str1_val1;
int str1_val2;
} struct1;
and
typedef struct
{
int str2_val1;
int str2_val2;
struct1* str2_val3;
} struct2;
Is it possible that I hack this definition in a way, that I would use only types with my code, like
struct2* a;
a = (struct2*) malloc(sizeof(struct2));
without using keyword struct?
Yes, as follows:
struct _struct1
{
...
};
typedef struct _struct1 struct1;
struct _struct2
{
...
};
typedef struct _struct2 struct2;
...
struct2 *a;
a = (struct2*)malloc(sizeof(struct2));
Yes, you can use the typedef'ed symbol without needing the struct keyword. The compiler simply uses that name as an alias for the structure you defined earlier.
One note on your example, malloc returns a pointer to memory. Hence your statement should read
a = (struct2 *)malloc(sizeof(struct2));
Just to share, I've seen this approach, and though I personally don't like it (I like everything named and tagged =P and I don't like using variable names in malloc), someone may.
typedef struct {
...
} *some_t;
int main() {
some_t var = (some_t) malloc(sizeof(*var));
}
as a footnote. If you code in C++ then you don't need to do the typedef; a struct is a type automatically.
I have a struct defined as:
struct {
char name[32];
int size;
int start;
int popularity;
} stasher_file;
and an array of pointers to those structs:
struct stasher_file *files[TOTAL_STORAGE_SIZE];
In my code, I'm making a pointer to the struct and setting its members, and adding it to the array:
...
struct stasher_file *newFile;
strncpy(newFile->name, name, 32);
newFile->size = size;
newFile->start = first_free;
newFile->popularity = 0;
files[num_files] = newFile;
...
I'm getting the following error:
error: dereferencing pointer to incomplete type
whenever I try to access the members inside newFile. What am I doing wrong?
You haven't defined struct stasher_file by your first definition. What you have defined is an nameless struct type and a variable stasher_file of that type. Since there's no definition for such type as struct stasher_file in your code, the compiler complains about incomplete type.
In order to define struct stasher_file, you should have done it as follows
struct stasher_file {
char name[32];
int size;
int start;
int popularity;
};
Note where the stasher_file name is placed in the definition.
You are using the pointer newFile without allocating space for it.
struct stasher_file *newFile = malloc(sizeof(stasher_file));
Also you should put the struct name at the top. Where you specified stasher_file is to create an instance of that struct.
struct stasher_file {
char name[32];
int size;
int start;
int popularity;
};
How did you actually define the structure? If
struct {
char name[32];
int size;
int start;
int popularity;
} stasher_file;
is to be taken as type definition, it's missing a typedef. When written as above, you actually define a variable called stasher_file, whose type is some anonymous struct type.
Try
typedef struct { ... } stasher_file;
(or, as already mentioned by others):
struct stasher_file { ... };
The latter actually matches your use of the type. The first form would require that you remove the struct before variable declarations.
the case above is for a new project. I hit upon this error while editing a fork of a well established library.
the typedef was included in the file I was editing but the struct wasn't.
The end result being that I was attempting to edit the struct in the wrong place.
If you run into this in a similar way look for other places where the struct is edited and try it there.
The reason why you're getting that error is because you've declared your struct as:
struct {
char name[32];
int size;
int start;
int popularity;
} stasher_file;
This is not declaring a stasher_file type. This is declaring an anonymous struct type and is creating a global instance named stasher_file.
What you intended was:
struct stasher_file {
char name[32];
int size;
int start;
int popularity;
};
But note that while Brian R. Bondy's response wasn't correct about your error message, he's right that you're trying to write into the struct without having allocated space for it. If you want an array of pointers to struct stasher_file structures, you'll need to call malloc to allocate space for each one:
struct stasher_file *newFile = malloc(sizeof *newFile);
if (newFile == NULL) {
/* Failure handling goes here. */
}
strncpy(newFile->name, name, 32);
newFile->size = size;
...
(BTW, be careful when using strncpy; it's not guaranteed to NUL-terminate.)
The reason is you did not declare type struct stasher_file, you define a struct variable stasher_file
instead.
In C, the declaration of structure:
struct structure-tag {
member1
member2
...
};
structure-tag is an optional name following the keyword struct.
After declaration, you can define a variable:
struct structure-tag var1, *var2;
Also, you can do both declaration and definition like:
struct structure-tag {
member1
member2
...
} var1, *var2;
So in your case, you could try this:
struct stasher_file {
char name[32];
int size;
int start;
int popularity;
} *files[TOTAL_STORAGE_SIZE];
struct stasher_file *newFile = malloc(sizeof(struct stasher_file));
... other code ...
That's all.