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.
Related
I have been trying something in structures in C.
struct val{
unsigned int a : 1 ;
}store[100] ;
Now I want to initialize all the array members value to 1. That is, I want all the array members to have their variable a assigned to 1. I can use a loop for that but how can I do this during the declaration?
struct val
{
unsigned int a=1 : 1 ;
}store[100];
How can i achieve this? The above syntax is coming out to be wrong in code::blocks.
struct val
{
unsigned int a : 1;
}store[100];
I initially thought that what you were doing was a bitfield initialization. Further research though suggested I am wrong, and that you are trying to use gcc's designated initializers. What you want to do, is not possible that way. I found another way in your code that you can do it, though:
typedef struct {
unsigned int a;
} val;
then, where you want to initialize the array, you will do something like that:
val values[100] = {[0].a = 1};
This works by exploiting this behavior of gcc:
If the same field is initialized multiple times, it has the value from the last initialization. If any such overridden initialization has side-effect, it is unspecified whether the side-effect happens or not. Currently, GCC discards them and issues a warning.
My Test Program follows:
#include <stdio.h>
struct val {
unsigned int a;
};
int
main (void)
{
struct val value[100] = {[0].a = 1};
printf ("A random val's value is %d\n", value[40].a);
return 0;
}
Compiles and works cleanly on my GCC 4.9.1.
It's not possible.
You can use a loop, or, if by any chance you want to initialize all struct's data members to a specific value, you can also use memset:
struct val {
unsigned int a : 1 ;
} store[N];
memset(store, value, N * sizeof(struct val));
Before declaring a struct variable you can't initialize its member. Initialization can be done as
struct val{
unsigned int a : 1;
}store[100] = {[0].a = 1} ; // Designated initializer
but it will initialize a member of other elements of store to 0. To initialize member a of all elements of store you need a loop.
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.
I was just wondering if a variable declared and defined inside a structure can be initialized to a certain value, was planning on using function pointers to mimic the classes in OOP.
Example COde:
typedef struct{
int x;
int (*manipulateX)(int) = &manipulateX;
}x = {0};
void main()
{
getch();
}
int manipulateX(int x)
{
x = x + 1;
return x;
}
Starting with C99, you can use designated initializers to set fields of structures to values, as follows:
struct MyStruct {
int x;
float f;
};
void test() {
struct MyStruct s = {.x=123, .f=456.789};
}
StructName s; // receives no initialization
StructName s = {x,y}; // value initializes all members
struct Child { StructName s; };
Child c; // receives no initialization
Child c = {x,y}; // value initializes all members
For Example :
struct Child{
int c;
int d;
}
Child childstruct ={10,20};
then childstruct.c will be 10
and childstruct.d will be 20.
http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7a.doc%2Flanguage%2Fref%2Fclrc03strin.htm
One approach which I've used when programming an embedded system where memory was somewhat tight was to use some macros to both define a structure type and define its initial value. The definition looked something like:
#define CREATE_FOO_STRUCT \
X(int age, 34) Y \
X(int height, 65) Y \
X(char const * favoritecolor,"blue") Y \
X(int some_things[5],ARR5(1,2,3,4,5))
The ARR5 macro was needed to allow the initialization values for that array to be passed as a single parameter; an alternative would have been to write the last line as X(int some_things[5],{1 COMMA 2 COMMA 3 COMMA 4 COMMA5}). Given a macro like the above, it is possible to define X and Y so X returns expands to first item and Y to semicolon, in which case typedef {CREATE_FOO_STRUCT} FOO; will define structure FOO, and then redefine X and Y so that X returns the second item and Y a comma, in which case const FOO default_FOO = {CREATE_FOO_STRUCT}; will define a default instance. It's too bad I don't know any way to avoid the need to have either the last line differ from the others (the last line could match the others if each line but the first was preceded by X, and if the last line was followed by a //this line must be left blank line.
On the particular processor where I implemented the above constructs, defining default_FOO in that way would consume zero RAM, and consume ROM equal to the size of default_FOO. A function which would load a static instance of FOO with the default values, using conventional assignment statement, would consume four bytes of ROM for each non-zero byte in default_FOO, and would also require that there be a static instance it could use. A C-language function which would accept a FOO* and load the pointed-to instance with default values would take a monstrous amount of code (each assignment would have to separately compute the address of the data to be stored).
it is illegal to initialize a structure member inside the structure template in C, and is not permitted.. as a struct template doesnot hold any memory of its own, and all the members of struct are allocated a memory space only when they are associated with a struct type of variable, and since now they are allocated a memory they can be initialized.. but not before getting associated with a variable: e.g
struct tag_name
{
int x;
int y;
};
the above struct template doesnot hold a memory space.. unless a variable is associated to it as:
struct tag_name variable1;
now the struct type of variable variable1 will be allocated a memory which is large enough to hold two int values(for variable1.x and variable1. y)
and now only you can initialize the members x and y as e.g.:
variable1.x=10;
variable1.y=20;
and hence the following would be illegal
struct tag_name
{
int x=10;
int y=20;
};
Let's say we have two struct types as follows:
struct A {
int a;
}
struct B {
int b;
int c;
}
Would it be possible to initialize a flexible-length array to contain instances of both A and B using designated initializers, e.g:
<sometype> my_array[] = {
((struct A){ .a = 10, }),
((struct B){ .b = 1, .c = 5, }),
};
And since I need to know the type of elements in the array, a way to put some char before the structs would be nice too. :)
I know this looks terribly broken, but I am trying to pack some bytecode-like data structures together and this looks like an elegant way to define them (well, with the help of some macros at least).
Edit: To clarify a few points:
Dynamic allocation is not an option
Neither are unions - I want the elements to occupy exactly the space needed by their type
"Variable length array" in the question could have been misleading - the exact denomination would be "flexible length array", according to http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html. The example code is ideally how I'd like it to look like.
So what I'd basically like is to be able to pack some arbitrary, structured data into a memory area that is allocated in the .data segment of the binary. I do not need random access to elements, just to pack the data from structs - the use of a flexible length array in my example is because this construct seems to be the closest from what I want to achieve. But the declaration could be anything else that does the job (except assembler, I need to retain C portability).
The best way for this would be to use unions. You could define all your types within a union, including this union and the char you wanna you for defining what is the actual type into a struct.
struct TypesAB {
char type;
union {
struct {
int a;
} A;
struct {
int b;
int c;
} B;
};
};
enum {
TypeA,
TypeB
};
With this struct, you can define your array, and then set the elements.
struct TypesAB array[10];
array[0].type = TypeA;
array[0].A.a = 10;
array[1].type = TypeB;
array[1].B.b = 1;
array[1].B.c = 5;
Note that the memory layout will make you loose some space if your A and B types are not the same length. Indeed, with the above definition, struct TypesAB will be defined with a sizeof large enough to hold the larger of the A or B, plus the char. If you use it as a A, then the memory space that would have been used for the c member is lost. The same memory space is used for the a member of A and the b member of B.
I'm trying to create structs with default values. I don't know how to accomplish this because every code that I see, is about initialising, and I would it for the natural way like...
struct stuff {
int stuff_a = 1;
int stuff_b = 2...
...and so on...
};
and looking about, I found this (C++) code:
struct a{ a() : i(0), j(0) {}; INT i; INT j;}
I never saw anything like this for C. Please, help me to understand it; I think that it is very nice!
UPDATE: Wait, I'm asking about C!!!! Why changed my question? If that is not possible in C just say... I don't know C++, I didn't know that was about C++...
If you want to set a struct object in one go and you have a C99 compiler, try this:
struct stuff {
int stuff_a;
int stuff_b;
// and so on...
};
struct stuff foo;
/* ... code ... */
foo = (struct stuff){.stuff_b = 42, .stuff_a = -1000};
Otherwise, with a C89 compiler, you have to set each member one by one:
foo.stuff_b = 42;
foo.stuff_a = -1000;
Running example # ideone : http://ideone.com/1QqCB
The original line
struct a{ a() : i(0), j(0) {} INT i; INT j;}
is a syntax error in C.
As you have probably learned from the other answers, in C you can't declare a structure and initialize it's members at the same time. These are different tasks and must be done separately.
There are a few options for initializing member variables of a struct. I'll show a couple of ways below. Right now, let's assume the following struct is defined in the beginning of the file:
struct stuff {
int stuff_a;
int stuff_b;
};
Then on your main() code, imagine that you want to declare a new variable of this type:
struct stuff custom_var;
This is the moment where you must initialize the structure. Seriously, I mean you really really must! Even if you don't want to assign specific values to them, you must at least initialize them to zero. This is mandatory because the OS doesn't guarantee that it will give you a clean memory space to run your application on. Therefore, always initialize your variables to some value (usually 0), including the other default types, such as char, int, float, double, etc...
One way to initialize our struct to zero is through memset():
memset(&custom_var, 0, sizeof(struct stuff));
Another is accessing each member individually:
custom_var.stuff_a = 0;
custom_var.stuff_b = 0;
A third option, which might confuse beginners is when they see the initialization of struct members being done at the moment of the declaration:
struct stuff custom_var = { 1, 2 };
The code above is equivalent to:
struct stuff custom_var;
custom_var.stuff_a = 1;
custom_var.stuff_b = 2;
... create structs with default values ...
That is impossible in C. A type cannot have default values. Objects of any type cannot have a default value other than 0, though they can be initialized to whatever is wanted.
The definition of a struct is a definition of a type, not of an object.
What you asking is about the same thing as a way to have ints default to, say, 42.
/* WRONG CODE -- THIS DOES NOT WORK */
typedef int int42 = 42;
int42 a;
printf("%d\n", a); /* print 42 */
Or, adapting to your example
/* WRONG CODE -- THIS DOES NOT WORK */
struct stuff {
int42 stuff_a;
int65536 stuff_b;
}
struct stuff a;
printf("%d\n", a.stuff_b); /* print 65536 */
Update: This answer assumes we 're talking about C++ because the code posted in the answer is not legal C.
struct a {
a() : i(0), j(0) {} // constructor with initialization list
int i;
int j;
}
The line marked with the comment is simply the constructor for instances of struct a (reminder: structs are just like classes, except that the default member visibility is public instead of private).
The part after the : is called an initialization list: it allows you to initialize the members of the struct with values (either constants or passed as constructor parameters). Initialization of members in this list happens before the body of the constructor is entered. It is preferable to initialize members of classes and structs this way, if at all possible.
See also C++: Constructor versus initializer list in struct/class.
in C (pre C99) the following also works:
#include <stdio.h>
typedef struct
{
int a;
int b;
int c;
} HELLO;
int main()
{
HELLO a = {1,2,3};
printf("here: %d %d %d\n",a.a,a.b,a.c);
exit(1);
}
See codepad
I'm not sure quite sure what your problem is. The standard way of initialising structures in c is like this:
struct a_struct my_struct = {1, 2};
Or the more recent and safer:
struct a_struct my_struct = {.i1 = 1, .i2 = 2};
If there is more than one instance of a structure, or it needs to be re-initialised, it is useful to define a constant structure with default values then assign that.
typedef struct a_struct {
int i1;
int i2;
} sa;
static const sa default_sa = {.i1 = 1, .i2 = 2};
static sa sa1 = default_sa;
static sa sa2 = default_sa;
// obviously you can do it dynamically as well
void use_temp_sa(void)
{
sa temp_sa = default_sa;
temp_sa.i2 = 3;
do_something_with(&temp_sa);
}
// And re-initialise
void reset_sa(sa *my_sa)
{
*my_sa = default_sa;
}
Type initializer is not possible in C.
A value must be stored in the memory.
A type does not occupy memory, what occupies memory is a variable of that type.
struct stuff; is a type; it does not occupy memory
struct stuff aStuff; is a variable of that type; aStuff occupies memory
Because a type does not occupy memory, it is not possible to save values into a type.
If there is syntactic sugar to support store/initialize values into a type then there must be additional code that is inserted to assign values to every instant variables of that type (e.g: in constructor in C++). This will result in a less efficient C if this feature is available.
How often do you need to retain this default values? I think it is unlikely. You can create a function to initialize variable with the default values or just initialize every fields with the values you want. So type initializer is not fundamental thing. C is about simplicity.
Can't initialize values within a structure definition.
I'd suggest:
typedef struct {
int stuff_a;
int stuff_b;
} stuff ;
int stuffInit(int a, int b, stuff *this){
this->stuff_a = a;
this->stuff_b = b;
return 0; /*or an error code, or sometimes '*this', per taste.*/
}
int main(void){
stuff myStuff;
stuffInit(1, 2, &myStuff);
/* dynamic is more commonly seen */
stuff *dynamicStuff;
dynamicStuff = malloc(sizeof(stuff)); /* 'new' stuff */
stuffInit(0, 0, dynamicStuff);
free(dynamicStuff); /* 'delete' stuff */
return 0;
}
Before the days of Object Oriented Programming (C++), we were taught "Abstract Data Types".
The discipline said 'never access your data structures directly, always create a function for it' But this was only enforced by the programmer, instructor, or senior developer, not the language.
Eventually, the structure definition(s) and corresponding functions end up in their own file & header, linked in later, further encapsulating the design.
But those days are gone and replaced with 'Class' and 'Constructor' OOP terminology.
"It's all the same, only the names have changed" - Bon Jovi.