Here is my problem, I try to initialize constant values from a struct, for simple values I do like this: *(int*)&myStruct->myValue = 1;
and it works very well but for the array I would have liked to use a similar method more than a 'memcpy' so I did like this:
*(MyOtherStruct*)&myStruct->myArrayOfStructs = {
otherStruct1, otherStruct2,
otherStruct3, otherStruct4
};
But I get this: error: expected expression before ‘{’ token
And I tried a lot of things but either it was totally buggy, or I had other error messages, I can't find the expression that the compiler wants and that works correctly...
Afterwards maybe the use of 'memcpy' is "obligated" but I will find it better without for my code if possible.
Thanks in advance !
EDIT: Here is an abstract but "working" example of what I want to do.
#include <stdlib.h>
typedef struct {
int r, g, b, a;
} Color;
typedef struct {
const int value;
const Color color[4];
} structExample;
int main(void)
{
Color colorWhite = { 0, 0, 0, 255 };
Color colorBlack = { 255, 255, 255, 255 };
Color colorRed = { 255, 0, 0, 255 };
Color colorBlue = { 0, 0, 255, 255 };
structExample* myStruct = malloc(sizeof(structExample));
*(int*)&myStruct->value = 1;
*(Color*)&myStruct->color = {
colorWhite, colorBlack,
colorRed, colorBlue
};
return 0;
}
You cannot assign an array, nor multiple elements of an array with one assignment. You can assign the elements of the array, for which you ought to do the casting correctly:
myStruct->color
is an array of 4 Color
. Taking its address yields a Color (*)4
. Casting that to Color *
leads to technical violations of rules required for the behavior to be define by the C standard.const
from the element. So simply take the address of an element instead of taking the address of the array:* (Color *) &myStruct->color[0] = colorWhite;
* (Color *) &myStruct->color[1] = colorBlack;
* (Color *) &myStruct->color[2] = colorRed;
* (Color *) &myStruct->color[3] = colorBlue;
However, this casting away of const
makes it irksome to avoid violating rules of the C standard regarding defined behavior. A better approach is:
const
from the member declarations in structExample
.const
involved.const
.When you do this, you can also use a compound literal to initialize the structure (even though it contains an array). Here is an example:
#include <stdlib.h>
typedef struct
{
int r, g, b, a;
} Color;
typedef struct
{
int value;
Color color[4];
} structExample;
int main(void)
{
Color colorWhite = { 0, 0, 0, 255 };
Color colorBlack = { 255, 255, 255, 255 };
Color colorRed = { 255, 0, 0, 255 };
Color colorBlue = { 0, 0, 255, 255 };
// Start with pointer to non-const object.
structExample *myStruct = malloc(sizeof *myStruct);
// Assign initial value.
*myStruct =
(structExample) { 1, { colorWhite, colorBlack, colorRed, colorBlue } };
// Convert to pointer to const object.
const structExample *myStructConst = myStruct;
// Use pointer-to-const for further work.
extern void foo(const structExample *);
foo(myStructConst);
/* Inside foo, only the pointer-to-const is seen, so it will get a
diagnostic message if it attempts to modify the structure without
using an explicit cast. foo does not see the original myStruct
pointer.
*/
// Use the original pointer to free.
free(myStruct);
}