What's the "dot" definition for struct attributes in C [duplicate] - c

This question already has answers here:
What does dot (.) mean in a struct initializer?
(4 answers)
Closed 9 years ago.
I wonder the meaning of attribute definitions with dot (.) for struct attributes in Redis source code :
struct config cfg = {
.tcp = {
.host = "127.0.0.1",
.port = 6379
},
.unix = {
.path = "/tmp/redis.sock"
}
};
Does it have a special meaning when you define an attribute with dot like .tcp = {...} ?
Thanks all.

It is a way to do named initialization of the struct members.
The default way to initialize a struct requires you to provide the arguments in the order the members were defined. This lets you you reorder that, and makes it more readable as well. This syntax also lets you initialize only a few members of the struct, esp. if they are not the first few. Take a look at this page.

... I wonder the meaning of attribute definitions with dot (.) for struct attributes ...
It allows for you to access a specific element of the structure using the initialization syntax { }. For example, consider this struct:
struct my_struct {
int field_1;
int field_2;
int field_3;
};
... it can be initialized as follows:
struct my_struct s1 = { 1, 2, 3 };
... or as follows:
struct my_struct s2 = { .field_1 = 1, .field_2 = 2, .field_3 = 3 };
... or if you do not know the order of the fields (or want to specify them in some order):
struct my_struct s3 = { .field_3 = 3, .field_1 = 1, .field_2 = 2 };
... remark that s1 is equivalent to s2 which is equivalent to s3. Moreover, if you do not specify a field in your initialization then it will be zero. From the C99 standard 6.7.8.21:
If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
... to illustrate this:
struct my_struct s4 = { .field_1 = 1 };
... that will zero-fill fields 2 and 3, hence s4.field_2 == 0 implies true.

Related

How to implement class and method in C? (e.g. Linux Kernel) [duplicate]

static struct fuse_oprations hello_oper = {
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};
I don't understand this C syntax well. I can't even search because I don't know the syntax's name. What's that?
This is a C99 feature that allows you to set specific fields of the struct by name in an initializer. Before this, the initializer needed to contain just the values, for all fields, in order -- which still works, of course.
So for the following struct:
struct demo_s {
int first;
int second;
int third;
};
...you can use
struct demo_s demo = { 1, 2, 3 };
...or:
struct demo_s demo = { .first = 1, .second = 2, .third = 3 };
...or even:
struct demo_s demo = { .first = 1, .third = 3, .second = 2 };
...though the last two are for C99 only.
These are C99's designated initializers.
Its known as designated initialisation (see Designated Initializers). An "initializer-list", Each '.' is a
"designator" which in this case names a particular member of the
'fuse_oprations' struct to initialize for the object designated by
the 'hello_oper' identifier.
The whole syntax is known as designated initializer as already mentioned by COD3BOY and it is used in general when you need to initialize your structure at the time of declaration to some specific or default values.

Is this stucture an array of structs? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
struct SOutputQuantity
{
TAnalogOutputQuantity outputQuantity;
TValueType valueType;
};
static struct SOutputQuantity _outputTypeToQuantityMap[] = {
{,},
{,},
};
This is a beginner's question but I have tried to understand the code but can't get it. What I don't understand from this code is, if this is an array of structures then why there is keyword struct before it?
you can always declare if something is a struct even if you have declared it before. it doesnt make a difference in the output of the program.
struct SOutputQuantity // Line 1: defines "struct SOutputQuantity"
{
TAnalogOutputQuantity outputQuantity;
TValueType valueType;
};
static struct SOutputQuantity _outputTypeToQuantityMap[] = { // Line 7: declars an array of SOutputQunantity
{,},
{,}
};
1) Line 1 defines a "struct" (a complex data record) that you can use later in your program.
2) You don't show how TAnalogOutputQuantity and TValueType are defined - they're probably in a "typedef" somehere else (possibly in a .hr header file).
3) You they declare a variable named "_outputTypeToQuantityMap".
4) "_outputTypeToQuantityMap" is an array of SOutputQuantity.
5) The "static" means that the name "_outputTypeToQuantityMap" is visible only in this module.
6) "{,}" is apparently intended to initialze two elements, each consisting of an outputQuantity and a valueType.
Q: Does the code snippet even compile?
C declarations can be difficult to understand without some practice. In the following, I'm ignoring some difficulties to do with pointers. There are lots of good references online that explain in more detail how C declarations work. That said, here's a simplified version of how to understand the code you give.
First, how do you declare an array a of N elements of some type T? In C, this is written as
T a[N];
Note that T is the type of the elements of A. This is true no matter what T is. For example,
int a[N];
char a[N];
In each case, the type of the array element comes first on the declaration. This is also true for structure types. Ie,
struct foo a[N];
declares an array a of N elements, each of which is a struct foo. In this case, unlike the previous two examples, there must be a definition of struct foo somewhere previously in source file or one of the included headers.
So, using the types from your example, the code
struct SOutputQuantity { /* ... */ };
static struct SOutputQuantity _outputTypeToQuantityMap[N];
declares _outputTypeToQuantityMap to be an array of N SOutputQuantity structures.
Quite rightly, you'll point out that this isn't identical to the code you showed. The final thing you're running into here is the concept of an initializer. Suppose you want to declare an array of 3 integers, and initialize that array at compile time. The syntax is
int a[3] = { 1, 2, 3 };
The compiler arranges (somehow, it doesn't really matter) that
a[0] == 1
a[1] == 2
a[2] == 3
before your program starts execution. Next, when you have an initializer for an arra declaration, you can leave out the number of elements in the array, because the compiler can figure it out. So,
int a[] = { 1, 2, 3 };
is identical to the previous declaration.
So now, the last few lines of your example code can be understood as
struct SOutputQuantity _outputTypeToQuantityMap[] = {
/* constant #1 */,
/* constant #2 */,
};
This code is declaring and initializing a two-element array. The only part left to understand is what {,} means. This is rather confusing on its own, and its the result of a sequence of shortcuts C makes available. Let's start without the array (and a simpler struct, so I don't have to type as much).
struct foo { int a; int b; };
struct foo x = { 1, 2 };
The second line of the above example declares and initializes a variable f of type struct foo so that
x.a == 1
x.b == 2
C allows you to omit omit trailing struct members from an initializer, filling in omitted values with zero. In particular, you can omit all struct members.
struct foo x = { 1 }; // x.a == 1; x.b == 0
struct foo x = { }; // x.a == 0; x.b == 0
Finally, C allows you to include a trailing comma after the last initializer:
struct foo x = { 1, 2, }; // x.a == 1; x.b == 2
struct foo x = { 1, }; // x.a == 1; x.b == 0
I'm not sure if it's allowed by the standard, but it appears that your compiler also allows
struct foo x = { , }; // x.a == 0; x.b == 0
So, after all that,
static struct SOutputQuantity _outputTypeToQuantityMap[] = {
{,},
{,},
};
declares a 2-element array with each element of type struct SOutputQuantity and simultaneously initializes each element of that array so that the outputQuantity and valueType fields are initialized to zero.

Strange structure definition

In code example of Intel DPDK i have found this strange syntactical construction. Can anybody explain me what does it mean?
static const struct rte_eth_conf port_conf = {
.rxmode = {
.split_hdr_size = 0,
.header_split = 0,
.hw_ip_checksum = 0,
.hw_vlan_filter = 0,
.jumbo_frame = 0,
.hw_strip_crc = 0,
},
.txmode = {
}
};
It's a C99 syntax known as a designated initializer.
In earlier C standards, the elements of a struct initializer had to appear in the same order as in the struct definition. With designated initializers, that restriction is lifted. Naturally the struct members have to be named to indicate which member is being initialized.
Designated initializers can also be used with arrays and allow you to initialize specific elements of an array. For example:
int a[6] = { [4] = 29, [2] = 15 };
If you have
struct X
{
type_a var_a;
type_b var_b;
type_c var_c;
type_d var_d;
};
you can initialize an object like this:
struct X x = {value_a, value_b, value_c, value_d};
But this means you need to know the order of variables in X as well as having an initial value for all of it. Alternatively, you can initialize like this:
struct X x = {
.var_a = value_a,
.var_b = value_b,
.var_c = value_c,
.var_d = value_d
};
This way, you can initialize member variables in any order, or even skip some.
This is specially useful in a library where you have some variables needed to be initialized by the user, while other variables are more internal and could even be changed with different versions of your library. Using this kind of initialization, the user doesn't need to know about those extra variables.
This is C99 feature called designated initializers. It lets you specify the names of the fields to which you set values, rather than specifying the values in the order the corresponding fields appear in the declaration. Additionally, this syntax lets you initialize members of unions other than the first one - something that was impossible before C99.

What does dot (.) mean in a struct initializer?

static struct fuse_oprations hello_oper = {
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};
I don't understand this C syntax well. I can't even search because I don't know the syntax's name. What's that?
This is a C99 feature that allows you to set specific fields of the struct by name in an initializer. Before this, the initializer needed to contain just the values, for all fields, in order -- which still works, of course.
So for the following struct:
struct demo_s {
int first;
int second;
int third;
};
...you can use
struct demo_s demo = { 1, 2, 3 };
...or:
struct demo_s demo = { .first = 1, .second = 2, .third = 3 };
...or even:
struct demo_s demo = { .first = 1, .third = 3, .second = 2 };
...though the last two are for C99 only.
These are C99's designated initializers.
Its known as designated initialisation (see Designated Initializers). An "initializer-list", Each '.' is a
"designator" which in this case names a particular member of the
'fuse_oprations' struct to initialize for the object designated by
the 'hello_oper' identifier.
The whole syntax is known as designated initializer as already mentioned by COD3BOY and it is used in general when you need to initialize your structure at the time of declaration to some specific or default values.

initialization of anonymous structures or unions in C1X

I have the following question: How are anonymous structures (or unions) properly initialized according to the current C1X draft? Is this legal:
struct foo {
int a;
struct {
int i;
int j;
};
int b;
};
struct foo f = { 1, 2, 3, 4 };
struct foo g = { 1, { 2 }, 3 };
In GCC, g.j == 0 and g.b == 3, while in tcc g.j == 3 and g.b == 0. The current draft says:
"[...] unnamed members of objects of structure and union type do not participate in initialization. Unnamed members of structure objects have indeterminate value even after initialization.".
Can this be really true? Isn't
struct foo h = { 0 };
supposed to set all members to 0?
Thanks very much!
UPDATE:
Since anonymous members seem to be only useful when mixing structs/unions, how to initialize this correctly:
struct bar {
int tag;
union {
double d;
int i;
};
};
? This gives errors in gcc < 4.6 and icc 11, but works in gcc 4.6, icc 12, clang and tcc:
struct bar a = { .tag = 1, .i = 42 };
This gives errors in clang and tcc, but works in gcc and icc:
struct bar b = { .tag = 1, { .i = 42 } };
Is the second one a violation of the standard?
f and h should correctly initialize all members, as i and j are to be treated like members of struct foo (C1x 6.7.2.1 §13):
The members of an anonymous structure
or union are considered to be members
of the containing structure or union.
I don't think that gcc's initialization of g is correct, considering C1x 6.7.9 §9:
Except where explicitly stated
otherwise, for the purposes of this
subclause unnamed members of objects
of structure and union type do not
participate in initialization.
§20 - which deals with sub-aggregates - contains no explicit statement relevant to the issue, so my best guess would be that §9 applies (but only to the aggregate itself, not to its members!).
The bottom line is that anonymous sub-aggregates don't exist as separate objects, ie tcc's behaviour should be correct...
Example code for my take on the issue:
struct foo
{
struct bar { int i; }; // (1) unnamed, but tagged, ie *not* anonymous
struct { int j; }; // (2) unnamed, but anonymous
struct { int k; } baz; // (3) named, but not tagged
};
(1) takes no part in initialization, (2) initializes as though struct foo had an additional member named j, (3) initializes as a regular sub-aggregate.
If my interpretation is correct, anonymous structures only make sense if contained within a union: an anonymous structure within a structure is indistinguishable from a flat structure containing additional members.
All members that have names in your structure can be initialized. You just can't initialize the intermediate structures as such. But
struct foo f = { .a = 1, .i = 2, .j = 3, .b = 4 };
should do it.
I haven't read the draft, I'm pretty sure unnamed and anonymous members are different. Unnamed would be something like
struct foo {
int bar:1; /* named */
int :31; /* unnamed */
};

Resources