Related
I want to initialize a struct element, split in declaration and initialization. This is what I have:
typedef struct MY_TYPE {
bool flag;
short int value;
double stuff;
} MY_TYPE;
void function(void) {
MY_TYPE a;
...
a = { true, 15, 0.123 }
}
Is this the way to declare and initialize a local variable of MY_TYPE in accordance with C programming language standards (C89, C90, C99, C11, etc.)? Or is there anything better or at least working?
Update I ended up having a static initialization element where I set every subelement according to my needs.
In (ANSI) C99, you can use a designated initializer to initialize a structure:
MY_TYPE a = { .flag = true, .value = 123, .stuff = 0.456 };
Other members are initialized as zero: "Omitted field members are implicitly initialized the same as objects that have static storage duration." (https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html)
You can do it with a compound literal. According to that page, it works in C99 (which also counts as ANSI C).
MY_TYPE a;
a = (MY_TYPE) { .flag = true, .value = 123, .stuff = 0.456 };
...
a = (MY_TYPE) { .value = 234, .stuff = 1.234, .flag = false };
The designations in the initializers are optional; you could also write:
a = (MY_TYPE) { true, 123, 0.456 };
...
a = (MY_TYPE) { false, 234, 1.234 };
I see you've already received an answer about ANSI C 99, so I'll throw a bone about ANSI C 89.
ANSI C 89 allows you to initialize a struct this way:
typedef struct Item {
int a;
float b;
char* name;
} Item;
int main(void) {
Item item = { 5, 2.2, "George" };
return 0;
}
An important thing to remember, at the moment you initialize even one object/ variable in the struct, all of its other variables will be initialized to default value.
If you don't initialize the values in your struct, all variables will contain "garbage values".
a = (MYTYPE){ true, 15, 0.123 };
would do fine in C99
C programming language standard ISO/IEC 9899:1999 (commonly known as C99) allows one to use a designated initializer to initialize members of a structure or union as follows:
MY_TYPE a = { .stuff = 0.456, .flag = true, .value = 123 };
It is defined in paragraph 7, section 6.7.8 Initialization of ISO/IEC 9899:1999 standard as:
If a designator has the form
. identifier
then the current object (defined below) shall have structure or union type and the identifier shall be the name of a member of that type.
Note that paragraph 9 of the same section states that:
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. Unnamed members of structure objects have indeterminate value even after initialization.
In GNU GCC implementation however omitted members are initialized as zero or zero-like type-appropriate value. As stated in section 6.27 Designated Initializers of GNU GCC documentation:
Omitted field members are implicitly initialized the same as objects that have static storage duration.
Microsoft Visual C++ compiler should support designated initializers since version 2013 according to official blog post C++ Conformance Roadmap. Paragraph Initializing unions and structs of Initializers article at MSDN Visual Studio documentation suggests that unnamed members initialized to zero-like appropriate values similarly to GNU GCC.
ISO/IEC 9899:2011 standard (commonly known as C11) which had superseded ISO/IEC 9899:1999 retains designated initializers under section 6.7.9 Initialization. It also retains paragraph 9 unchanged.
New ISO/IEC 9899:2018 standard (commonly known as C18) which had superseded ISO/IEC 9899:2011 retains designated initializers under section 6.7.9 Initialization. It also retains paragraph 9 unchanged.
You've almost got it...
MY_TYPE a = { true, 15, 0.123 };
Quick search on 'struct initialize c' shows me this
Adding to All of these good answer a summary to how to initialize a structure (union and Array) in C, focused especially on the Designed Initializer.
Standard Initialization
struct point
{
double x;
double y;
double z;
}
p = {1.2, 1.3};
Designated Initializer
The Designated Initializer came up since the ISO C99 and is a different and more dynamic way to initialize in C when initializing struct, union or an array.
The biggest difference to standard initialization is that you don't have to declare the elements in a fixed order and you can also omit element.
From The GNU Guide:
Standard C90 requires the elements of an initializer to appear in a fixed order, the same as the order of the elements in the array or structure being initialized.
In ISO C99 you can give the elements in random order, specifying the array indices or structure field names they apply to, and GNU C allows this as an extension in C90 mode as well
Examples
1. Array Index
Standard Initialization
int a[6] = { 0, 0, 15, 0, 29, 0 };
Designated Initialization
int a[6] = {[4] = 29, [2] = 15 }; // or
int a[6] = {[4]29 , [2]15 }; // or
int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
2. Struct or union:
Standard Initialization
struct point { int x, y; };
Designated Initialization
struct point p = { .y = 2, .x = 3 }; or
struct point p = { y: 2, x: 3 };
3. Combine naming elements with ordinary C initialization of successive elements:
Standard Initialization
int a[6] = { 0, v1, v2, 0, v4, 0 };
Designated Initialization
int a[6] = { [1] = v1, v2, [4] = v4 };
4. Others:
Labeling the elements of an array initializer
int whitespace[256] = { [' '] = 1, ['\t'] = 1, ['\h'] = 1,
['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };
write a series of ‘.fieldname’ and ‘[index]’ designators before an ‘=’ to specify a nested subobject to initialize
struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 };
Guides
designated-initializers-c | geeksforgeeks.org
using-designated-initializers
tutorialspoint.com | designated-initializers-in-c
as Ron Nuni said:
typedef struct Item {
int a;
float b;
char* name;
} Item;
int main(void) {
Item item = {5, 2.2, "George"};
return 0;
}
An important thing to remember: at the moment you initialize even one object/variable in the struct, all of its other variables will be initialized to default value.
If you don't initialize the values in your struct (i.e. if you just declare that variable), all variable.members will contain "garbage values", only if the declaration is local!
If the declaration is global or static (like in this case), all uninitialized variable.members will be initialized automatically to:
0 for integers and floating point
'\0' for char (of course this is just the same as 0, and char is an integer type)
NULL for pointers.
This can be done in different ways:
MY_TYPE a = { true, 1, 0.1 };
MY_TYPE a = { .stuff = 0.1, .flag = true, .value = 1 }; //designated initializer, not available in c++
MY_TYPE a;
a = (MY_TYPE) { true, 1, 0.1 };
MY_TYPE m (true, 1, 0.1); //works in C++, not available in C
Also, you can define member while declaring structure.
#include <stdio.h>
struct MY_TYPE
{
int a;
int b;
}m = {5,6};
int main()
{
printf("%d %d\n",m.a,m.b);
return 0;
}
I didn't like any of these answers so I made my own. I don't know if this is ANSI C or not, it's just GCC 4.2.1 in it's default mode. I never can remember the bracketing so I start with a subset of my data and do battle with compiler error messages until it shuts up. Readability is my first priority.
// in a header:
typedef unsigned char uchar;
struct fields {
uchar num;
uchar lbl[35];
};
// in an actual c file (I have 2 in this case)
struct fields labels[] = {
{0, "Package"},
{1, "Version"},
{2, "Apport"},
{3, "Architecture"},
{4, "Bugs"},
{5, "Description-md5"},
{6, "Essential"},
{7, "Filename"},
{8, "Ghc-Package"},
{9, "Gstreamer-Version"},
{10, "Homepage"},
{11, "Installed-Size"},
{12, "MD5sum"},
{13, "Maintainer"},
{14, "Modaliases"},
{15, "Multi-Arch"},
{16, "Npp-Description"},
{17, "Npp-File"},
{18, "Npp-Name"},
{19, "Origin"}
};
The data may start life as a tab-delimited file that you search-replace to massage into something else. Yes, this is Debian stuff. So one outside pair of {} (indicating the array), then another pair for each struct inside. With commas between. Putting things in a header isn't strictly necessary, but I've got about 50 items in my struct so I want them in a separate file, both to keep the mess out of my code and so it's easier to replace.
void function(void) {
MY_TYPE a;
a.flag = true;
a.value = 15;
a.stuff = 0.123;
}
I found another way to initialize structs.
The struct:
typedef struct test {
int num;
char* str;
} test;
Initialization:
test tt = {
num: 42,
str: "nice"
};
As per GCC’s documentation, this syntax is obsolete since GCC 2.5.
If MS has not updated to C99, MY_TYPE a = { true,15,0.123 };
Structure in C can be declared and initialized like this:
typedef struct book
{
char title[10];
char author[10];
float price;
} book;
int main() {
book b1={"DS", "Ajay", 250.0};
printf("%s \t %s \t %f", b1.title, b1.author, b1.price);
return 0;
}
I have read the Microsoft Visual Studio 2015 Documentation for Initializing Aggregate Types yet, all forms of initializing with {...} are explained there, but the initializing with dot, named ''designator'' isn't mentioned there. It does not work also.
The C99 standard chapter 6.7.8 Initialization explains the possibility of designators, but in my mind it is not really clear for complex structs. The C99 standard as pdf .
In my mind, it may be better to
Use the = {0};-initialization for all static data. It is less effort for the machine code.
Use macros for initializing, for example
typedef MyStruct_t{ int x, int a, int b; } MyStruct;
define INIT_MyStruct(A,B) { 0, A, B}
The macro can be adapted, its argument list can be independent of changed struct content. It is proper if less elements should be initialized. It is also proper for nested struct.
3. A simple form is: Initialize in a subroutine:
void init_MyStruct(MyStruct* thiz, int a, int b) {
thiz->a = a; thiz->b = b; }
This routine looks like ObjectOriented in C. Use thiz, not this to compile it with C++ too!
MyStruct data = {0}; //all is zero!
init_MyStruct(&data, 3, 456);
I've been looking for a nice way to initialize my struct, and I've got to using the below (C99). This lets me initialize either a single structure or an array of structures in the same way as plain types.
typedef struct {
char *str;
size_t len;
jsmntok_t *tok;
int tsz;
} jsmn_ts;
#define jsmn_ts_default (jsmn_ts){NULL, 0, NULL, 0}
This can be used in the code as:
jsmn_ts mydata = jsmn_ts_default; /* initialization of a single struct */
jsmn_ts myarray[10] = {jsmn_ts_default, jsmn_ts_default}; /* initialization of
first 2 structs in the array */
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.
I want to initialize a struct element, split in declaration and initialization. This is what I have:
typedef struct MY_TYPE {
bool flag;
short int value;
double stuff;
} MY_TYPE;
void function(void) {
MY_TYPE a;
...
a = { true, 15, 0.123 }
}
Is this the way to declare and initialize a local variable of MY_TYPE in accordance with C programming language standards (C89, C90, C99, C11, etc.)? Or is there anything better or at least working?
Update I ended up having a static initialization element where I set every subelement according to my needs.
In (ANSI) C99, you can use a designated initializer to initialize a structure:
MY_TYPE a = { .flag = true, .value = 123, .stuff = 0.456 };
Other members are initialized as zero: "Omitted field members are implicitly initialized the same as objects that have static storage duration." (https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html)
You can do it with a compound literal. According to that page, it works in C99 (which also counts as ANSI C).
MY_TYPE a;
a = (MY_TYPE) { .flag = true, .value = 123, .stuff = 0.456 };
...
a = (MY_TYPE) { .value = 234, .stuff = 1.234, .flag = false };
The designations in the initializers are optional; you could also write:
a = (MY_TYPE) { true, 123, 0.456 };
...
a = (MY_TYPE) { false, 234, 1.234 };
I see you've already received an answer about ANSI C 99, so I'll throw a bone about ANSI C 89.
ANSI C 89 allows you to initialize a struct this way:
typedef struct Item {
int a;
float b;
char* name;
} Item;
int main(void) {
Item item = { 5, 2.2, "George" };
return 0;
}
An important thing to remember, at the moment you initialize even one object/ variable in the struct, all of its other variables will be initialized to default value.
If you don't initialize the values in your struct, all variables will contain "garbage values".
a = (MYTYPE){ true, 15, 0.123 };
would do fine in C99
C programming language standard ISO/IEC 9899:1999 (commonly known as C99) allows one to use a designated initializer to initialize members of a structure or union as follows:
MY_TYPE a = { .stuff = 0.456, .flag = true, .value = 123 };
It is defined in paragraph 7, section 6.7.8 Initialization of ISO/IEC 9899:1999 standard as:
If a designator has the form
. identifier
then the current object (defined below) shall have structure or union type and the identifier shall be the name of a member of that type.
Note that paragraph 9 of the same section states that:
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. Unnamed members of structure objects have indeterminate value even after initialization.
In GNU GCC implementation however omitted members are initialized as zero or zero-like type-appropriate value. As stated in section 6.27 Designated Initializers of GNU GCC documentation:
Omitted field members are implicitly initialized the same as objects that have static storage duration.
Microsoft Visual C++ compiler should support designated initializers since version 2013 according to official blog post C++ Conformance Roadmap. Paragraph Initializing unions and structs of Initializers article at MSDN Visual Studio documentation suggests that unnamed members initialized to zero-like appropriate values similarly to GNU GCC.
ISO/IEC 9899:2011 standard (commonly known as C11) which had superseded ISO/IEC 9899:1999 retains designated initializers under section 6.7.9 Initialization. It also retains paragraph 9 unchanged.
New ISO/IEC 9899:2018 standard (commonly known as C18) which had superseded ISO/IEC 9899:2011 retains designated initializers under section 6.7.9 Initialization. It also retains paragraph 9 unchanged.
You've almost got it...
MY_TYPE a = { true, 15, 0.123 };
Quick search on 'struct initialize c' shows me this
Adding to All of these good answer a summary to how to initialize a structure (union and Array) in C, focused especially on the Designed Initializer.
Standard Initialization
struct point
{
double x;
double y;
double z;
}
p = {1.2, 1.3};
Designated Initializer
The Designated Initializer came up since the ISO C99 and is a different and more dynamic way to initialize in C when initializing struct, union or an array.
The biggest difference to standard initialization is that you don't have to declare the elements in a fixed order and you can also omit element.
From The GNU Guide:
Standard C90 requires the elements of an initializer to appear in a fixed order, the same as the order of the elements in the array or structure being initialized.
In ISO C99 you can give the elements in random order, specifying the array indices or structure field names they apply to, and GNU C allows this as an extension in C90 mode as well
Examples
1. Array Index
Standard Initialization
int a[6] = { 0, 0, 15, 0, 29, 0 };
Designated Initialization
int a[6] = {[4] = 29, [2] = 15 }; // or
int a[6] = {[4]29 , [2]15 }; // or
int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
2. Struct or union:
Standard Initialization
struct point { int x, y; };
Designated Initialization
struct point p = { .y = 2, .x = 3 }; or
struct point p = { y: 2, x: 3 };
3. Combine naming elements with ordinary C initialization of successive elements:
Standard Initialization
int a[6] = { 0, v1, v2, 0, v4, 0 };
Designated Initialization
int a[6] = { [1] = v1, v2, [4] = v4 };
4. Others:
Labeling the elements of an array initializer
int whitespace[256] = { [' '] = 1, ['\t'] = 1, ['\h'] = 1,
['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };
write a series of ‘.fieldname’ and ‘[index]’ designators before an ‘=’ to specify a nested subobject to initialize
struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 };
Guides
designated-initializers-c | geeksforgeeks.org
using-designated-initializers
tutorialspoint.com | designated-initializers-in-c
as Ron Nuni said:
typedef struct Item {
int a;
float b;
char* name;
} Item;
int main(void) {
Item item = {5, 2.2, "George"};
return 0;
}
An important thing to remember: at the moment you initialize even one object/variable in the struct, all of its other variables will be initialized to default value.
If you don't initialize the values in your struct (i.e. if you just declare that variable), all variable.members will contain "garbage values", only if the declaration is local!
If the declaration is global or static (like in this case), all uninitialized variable.members will be initialized automatically to:
0 for integers and floating point
'\0' for char (of course this is just the same as 0, and char is an integer type)
NULL for pointers.
This can be done in different ways:
MY_TYPE a = { true, 1, 0.1 };
MY_TYPE a = { .stuff = 0.1, .flag = true, .value = 1 }; //designated initializer, not available in c++
MY_TYPE a;
a = (MY_TYPE) { true, 1, 0.1 };
MY_TYPE m (true, 1, 0.1); //works in C++, not available in C
Also, you can define member while declaring structure.
#include <stdio.h>
struct MY_TYPE
{
int a;
int b;
}m = {5,6};
int main()
{
printf("%d %d\n",m.a,m.b);
return 0;
}
I didn't like any of these answers so I made my own. I don't know if this is ANSI C or not, it's just GCC 4.2.1 in it's default mode. I never can remember the bracketing so I start with a subset of my data and do battle with compiler error messages until it shuts up. Readability is my first priority.
// in a header:
typedef unsigned char uchar;
struct fields {
uchar num;
uchar lbl[35];
};
// in an actual c file (I have 2 in this case)
struct fields labels[] = {
{0, "Package"},
{1, "Version"},
{2, "Apport"},
{3, "Architecture"},
{4, "Bugs"},
{5, "Description-md5"},
{6, "Essential"},
{7, "Filename"},
{8, "Ghc-Package"},
{9, "Gstreamer-Version"},
{10, "Homepage"},
{11, "Installed-Size"},
{12, "MD5sum"},
{13, "Maintainer"},
{14, "Modaliases"},
{15, "Multi-Arch"},
{16, "Npp-Description"},
{17, "Npp-File"},
{18, "Npp-Name"},
{19, "Origin"}
};
The data may start life as a tab-delimited file that you search-replace to massage into something else. Yes, this is Debian stuff. So one outside pair of {} (indicating the array), then another pair for each struct inside. With commas between. Putting things in a header isn't strictly necessary, but I've got about 50 items in my struct so I want them in a separate file, both to keep the mess out of my code and so it's easier to replace.
void function(void) {
MY_TYPE a;
a.flag = true;
a.value = 15;
a.stuff = 0.123;
}
I found another way to initialize structs.
The struct:
typedef struct test {
int num;
char* str;
} test;
Initialization:
test tt = {
num: 42,
str: "nice"
};
As per GCC’s documentation, this syntax is obsolete since GCC 2.5.
If MS has not updated to C99, MY_TYPE a = { true,15,0.123 };
Structure in C can be declared and initialized like this:
typedef struct book
{
char title[10];
char author[10];
float price;
} book;
int main() {
book b1={"DS", "Ajay", 250.0};
printf("%s \t %s \t %f", b1.title, b1.author, b1.price);
return 0;
}
I have read the Microsoft Visual Studio 2015 Documentation for Initializing Aggregate Types yet, all forms of initializing with {...} are explained there, but the initializing with dot, named ''designator'' isn't mentioned there. It does not work also.
The C99 standard chapter 6.7.8 Initialization explains the possibility of designators, but in my mind it is not really clear for complex structs. The C99 standard as pdf .
In my mind, it may be better to
Use the = {0};-initialization for all static data. It is less effort for the machine code.
Use macros for initializing, for example
typedef MyStruct_t{ int x, int a, int b; } MyStruct;
define INIT_MyStruct(A,B) { 0, A, B}
The macro can be adapted, its argument list can be independent of changed struct content. It is proper if less elements should be initialized. It is also proper for nested struct.
3. A simple form is: Initialize in a subroutine:
void init_MyStruct(MyStruct* thiz, int a, int b) {
thiz->a = a; thiz->b = b; }
This routine looks like ObjectOriented in C. Use thiz, not this to compile it with C++ too!
MyStruct data = {0}; //all is zero!
init_MyStruct(&data, 3, 456);
I've been looking for a nice way to initialize my struct, and I've got to using the below (C99). This lets me initialize either a single structure or an array of structures in the same way as plain types.
typedef struct {
char *str;
size_t len;
jsmntok_t *tok;
int tsz;
} jsmn_ts;
#define jsmn_ts_default (jsmn_ts){NULL, 0, NULL, 0}
This can be used in the code as:
jsmn_ts mydata = jsmn_ts_default; /* initialization of a single struct */
jsmn_ts myarray[10] = {jsmn_ts_default, jsmn_ts_default}; /* initialization of
first 2 structs in the array */
I found some struct initialization code yesterday that threw me for a loop. Here's an example:
typedef struct { int first; int second; } TEST_STRUCT;
void testFunc() {
TEST_STRUCT test = {
second: 2,
first: 1
};
printf("test.first=%d test.second=%d\n", test.first, test.second);
}
Surprisingly (to me), here's the output:
-> testFunc
test.first=1 test.second=2
As you can see, the struct gets initialized properly. I wasn't aware labeled statements could be used like that. I've seen several other ways of doing struct initialization, but I didn't find any examples of this sort of struct initialization on any of the online C FAQs. Is anybody aware of how/why this works?
Here is the section of the gcc manual which explains the syntax of designated initializers for both structs and arrays:
In a structure initializer, specify the name of a field to initialize
with '.fieldname =' before the element value. For example, given the
following structure,
struct point { int x, y; };
the following initialization
struct point p = { .y = yvalue, .x = xvalue };
is equivalent to
struct point p = { xvalue, yvalue };
Another syntax which has the same meaning, obsolete since GCC 2.5, is 'fieldname:', as shown here:
struct point p = { y: yvalue, x: xvalue };
The relevant page can be found here.
Your compiler should have similar documentation.
These are neither labels nor bitfields.
This is a syntax to initialize struct members dating back to the days before C99. It is not standardized but available in e.g. gcc.
typedef struct { int y; int x; } POINT;
POINT p = { x: 1, y: 17 };
In C99, syntax for initializing specific struct members has been introduced for the first time in a standard, but it looks a little differently:
typedef struct { int y; int x; } POINT;
POINT p = { .x = 1, .y = 17 };
Yes, as pointed out above, these are designated initializers, which are standard C, though you should switch to using periods instead of colons. And as you note, most of the books out there are still stuck somewhere around 1984 in their syntax and fail to mention them. More fun facts:
--When using designated initializers, everything not specified is initialized at zero. This helps with exceptionally large structs, e.g.:
typedef struct {
double a, b, c, d, e;
char label[100];
} too_many_type;
too_many_type tm = {.a = 1, .e = 2, .b=1.5};
assert(tm.a + tm.b + tm.c + tm.d + tm.e == 4.5);
assert(!strlen(label));
--Also, you can use the compound literal form to use this form on a non-initialization line, e.g.:
too_many_type tm2;
tm2 = (too_many_type) {.a = 3, .e=6};
These are really great features, and are supported by every C compiler that I can think of, being that it's the standard. It's a shame that they're not so well known.
It's not really "labeled statements", but a way to give initial values to the named fields in the struct.
Gcc gives a warning about "obsolete use of designated initializer with ':'", and in C99 you should instead write:
TEST_STRUCT test = {
.second = 2,
.first = 1
};
That syntax is not defined by the C Standard. Section 6.7.8 Initialization says
designation:
designator-list =
designator-list:
designator
designator-list designator
designator:
[ constant-expression ]
. identifier
If your compiler accepts a designation with a colon without a diagnostic message it means your compiler is not (or is configured not to be) Standards compliant.
I want to initialize a struct element, split in declaration and initialization. This is what I have:
typedef struct MY_TYPE {
bool flag;
short int value;
double stuff;
} MY_TYPE;
void function(void) {
MY_TYPE a;
...
a = { true, 15, 0.123 }
}
Is this the way to declare and initialize a local variable of MY_TYPE in accordance with C programming language standards (C89, C90, C99, C11, etc.)? Or is there anything better or at least working?
Update I ended up having a static initialization element where I set every subelement according to my needs.
In (ANSI) C99, you can use a designated initializer to initialize a structure:
MY_TYPE a = { .flag = true, .value = 123, .stuff = 0.456 };
Other members are initialized as zero: "Omitted field members are implicitly initialized the same as objects that have static storage duration." (https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html)
You can do it with a compound literal. According to that page, it works in C99 (which also counts as ANSI C).
MY_TYPE a;
a = (MY_TYPE) { .flag = true, .value = 123, .stuff = 0.456 };
...
a = (MY_TYPE) { .value = 234, .stuff = 1.234, .flag = false };
The designations in the initializers are optional; you could also write:
a = (MY_TYPE) { true, 123, 0.456 };
...
a = (MY_TYPE) { false, 234, 1.234 };
I see you've already received an answer about ANSI C 99, so I'll throw a bone about ANSI C 89.
ANSI C 89 allows you to initialize a struct this way:
typedef struct Item {
int a;
float b;
char* name;
} Item;
int main(void) {
Item item = { 5, 2.2, "George" };
return 0;
}
An important thing to remember, at the moment you initialize even one object/ variable in the struct, all of its other variables will be initialized to default value.
If you don't initialize the values in your struct, all variables will contain "garbage values".
a = (MYTYPE){ true, 15, 0.123 };
would do fine in C99
C programming language standard ISO/IEC 9899:1999 (commonly known as C99) allows one to use a designated initializer to initialize members of a structure or union as follows:
MY_TYPE a = { .stuff = 0.456, .flag = true, .value = 123 };
It is defined in paragraph 7, section 6.7.8 Initialization of ISO/IEC 9899:1999 standard as:
If a designator has the form
. identifier
then the current object (defined below) shall have structure or union type and the identifier shall be the name of a member of that type.
Note that paragraph 9 of the same section states that:
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. Unnamed members of structure objects have indeterminate value even after initialization.
In GNU GCC implementation however omitted members are initialized as zero or zero-like type-appropriate value. As stated in section 6.27 Designated Initializers of GNU GCC documentation:
Omitted field members are implicitly initialized the same as objects that have static storage duration.
Microsoft Visual C++ compiler should support designated initializers since version 2013 according to official blog post C++ Conformance Roadmap. Paragraph Initializing unions and structs of Initializers article at MSDN Visual Studio documentation suggests that unnamed members initialized to zero-like appropriate values similarly to GNU GCC.
ISO/IEC 9899:2011 standard (commonly known as C11) which had superseded ISO/IEC 9899:1999 retains designated initializers under section 6.7.9 Initialization. It also retains paragraph 9 unchanged.
New ISO/IEC 9899:2018 standard (commonly known as C18) which had superseded ISO/IEC 9899:2011 retains designated initializers under section 6.7.9 Initialization. It also retains paragraph 9 unchanged.
You've almost got it...
MY_TYPE a = { true, 15, 0.123 };
Quick search on 'struct initialize c' shows me this
Adding to All of these good answer a summary to how to initialize a structure (union and Array) in C, focused especially on the Designed Initializer.
Standard Initialization
struct point
{
double x;
double y;
double z;
}
p = {1.2, 1.3};
Designated Initializer
The Designated Initializer came up since the ISO C99 and is a different and more dynamic way to initialize in C when initializing struct, union or an array.
The biggest difference to standard initialization is that you don't have to declare the elements in a fixed order and you can also omit element.
From The GNU Guide:
Standard C90 requires the elements of an initializer to appear in a fixed order, the same as the order of the elements in the array or structure being initialized.
In ISO C99 you can give the elements in random order, specifying the array indices or structure field names they apply to, and GNU C allows this as an extension in C90 mode as well
Examples
1. Array Index
Standard Initialization
int a[6] = { 0, 0, 15, 0, 29, 0 };
Designated Initialization
int a[6] = {[4] = 29, [2] = 15 }; // or
int a[6] = {[4]29 , [2]15 }; // or
int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
2. Struct or union:
Standard Initialization
struct point { int x, y; };
Designated Initialization
struct point p = { .y = 2, .x = 3 }; or
struct point p = { y: 2, x: 3 };
3. Combine naming elements with ordinary C initialization of successive elements:
Standard Initialization
int a[6] = { 0, v1, v2, 0, v4, 0 };
Designated Initialization
int a[6] = { [1] = v1, v2, [4] = v4 };
4. Others:
Labeling the elements of an array initializer
int whitespace[256] = { [' '] = 1, ['\t'] = 1, ['\h'] = 1,
['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };
write a series of ‘.fieldname’ and ‘[index]’ designators before an ‘=’ to specify a nested subobject to initialize
struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 };
Guides
designated-initializers-c | geeksforgeeks.org
using-designated-initializers
tutorialspoint.com | designated-initializers-in-c
as Ron Nuni said:
typedef struct Item {
int a;
float b;
char* name;
} Item;
int main(void) {
Item item = {5, 2.2, "George"};
return 0;
}
An important thing to remember: at the moment you initialize even one object/variable in the struct, all of its other variables will be initialized to default value.
If you don't initialize the values in your struct (i.e. if you just declare that variable), all variable.members will contain "garbage values", only if the declaration is local!
If the declaration is global or static (like in this case), all uninitialized variable.members will be initialized automatically to:
0 for integers and floating point
'\0' for char (of course this is just the same as 0, and char is an integer type)
NULL for pointers.
This can be done in different ways:
MY_TYPE a = { true, 1, 0.1 };
MY_TYPE a = { .stuff = 0.1, .flag = true, .value = 1 }; //designated initializer, not available in c++
MY_TYPE a;
a = (MY_TYPE) { true, 1, 0.1 };
MY_TYPE m (true, 1, 0.1); //works in C++, not available in C
Also, you can define member while declaring structure.
#include <stdio.h>
struct MY_TYPE
{
int a;
int b;
}m = {5,6};
int main()
{
printf("%d %d\n",m.a,m.b);
return 0;
}
I didn't like any of these answers so I made my own. I don't know if this is ANSI C or not, it's just GCC 4.2.1 in it's default mode. I never can remember the bracketing so I start with a subset of my data and do battle with compiler error messages until it shuts up. Readability is my first priority.
// in a header:
typedef unsigned char uchar;
struct fields {
uchar num;
uchar lbl[35];
};
// in an actual c file (I have 2 in this case)
struct fields labels[] = {
{0, "Package"},
{1, "Version"},
{2, "Apport"},
{3, "Architecture"},
{4, "Bugs"},
{5, "Description-md5"},
{6, "Essential"},
{7, "Filename"},
{8, "Ghc-Package"},
{9, "Gstreamer-Version"},
{10, "Homepage"},
{11, "Installed-Size"},
{12, "MD5sum"},
{13, "Maintainer"},
{14, "Modaliases"},
{15, "Multi-Arch"},
{16, "Npp-Description"},
{17, "Npp-File"},
{18, "Npp-Name"},
{19, "Origin"}
};
The data may start life as a tab-delimited file that you search-replace to massage into something else. Yes, this is Debian stuff. So one outside pair of {} (indicating the array), then another pair for each struct inside. With commas between. Putting things in a header isn't strictly necessary, but I've got about 50 items in my struct so I want them in a separate file, both to keep the mess out of my code and so it's easier to replace.
void function(void) {
MY_TYPE a;
a.flag = true;
a.value = 15;
a.stuff = 0.123;
}
I found another way to initialize structs.
The struct:
typedef struct test {
int num;
char* str;
} test;
Initialization:
test tt = {
num: 42,
str: "nice"
};
As per GCC’s documentation, this syntax is obsolete since GCC 2.5.
If MS has not updated to C99, MY_TYPE a = { true,15,0.123 };
Structure in C can be declared and initialized like this:
typedef struct book
{
char title[10];
char author[10];
float price;
} book;
int main() {
book b1={"DS", "Ajay", 250.0};
printf("%s \t %s \t %f", b1.title, b1.author, b1.price);
return 0;
}
I have read the Microsoft Visual Studio 2015 Documentation for Initializing Aggregate Types yet, all forms of initializing with {...} are explained there, but the initializing with dot, named ''designator'' isn't mentioned there. It does not work also.
The C99 standard chapter 6.7.8 Initialization explains the possibility of designators, but in my mind it is not really clear for complex structs. The C99 standard as pdf .
In my mind, it may be better to
Use the = {0};-initialization for all static data. It is less effort for the machine code.
Use macros for initializing, for example
typedef MyStruct_t{ int x, int a, int b; } MyStruct;
define INIT_MyStruct(A,B) { 0, A, B}
The macro can be adapted, its argument list can be independent of changed struct content. It is proper if less elements should be initialized. It is also proper for nested struct.
3. A simple form is: Initialize in a subroutine:
void init_MyStruct(MyStruct* thiz, int a, int b) {
thiz->a = a; thiz->b = b; }
This routine looks like ObjectOriented in C. Use thiz, not this to compile it with C++ too!
MyStruct data = {0}; //all is zero!
init_MyStruct(&data, 3, 456);
I've been looking for a nice way to initialize my struct, and I've got to using the below (C99). This lets me initialize either a single structure or an array of structures in the same way as plain types.
typedef struct {
char *str;
size_t len;
jsmntok_t *tok;
int tsz;
} jsmn_ts;
#define jsmn_ts_default (jsmn_ts){NULL, 0, NULL, 0}
This can be used in the code as:
jsmn_ts mydata = jsmn_ts_default; /* initialization of a single struct */
jsmn_ts myarray[10] = {jsmn_ts_default, jsmn_ts_default}; /* initialization of
first 2 structs in the array */