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;
}
CodePudding user response:
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 4Color
. Taking its address yields aColor (*)4
. Casting that toColor *
leads to technical violations of rules required for the behavior to be define by the C standard.- Your goal is to remove
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:
- Remove the
const
from the member declarations instructExample
. - Allocate memory and initialize the structure with no
const
involved. - Assign the pointer to the memory to a new pointer that does have
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);
}
CodePudding user response:
You cant assign the arrays. You need to do this manually
myStruct->myArrayOfStructs[0] = otherStruct1;
myStruct->myArrayOfStructs[1] = otherStruct2;
myStruct->myArrayOfStructs[2] = otherStruct3;
myStruct->myArrayOfStructs[3] = otherStruct4;