I'm making a Camera struct. the struct use a vec3
which is defined with typedef float vec3[3]
.
To initialize a vec3
I do vec3 vector = {0.,0.,0.};
My Cameras
struct is like this:
typedef struct Cameras {
vec3 eye;
vec3 target
} Camera;
but when I do:
Camera cam;
cam.eye = { .5, 1., 0. };
it crashes and the compiler tells me: expression must be modifiable
.
I thought it was an error with pointer but no, and replacing vec3 eye
to vec3 * eye
and cam->eye = {.5,1.,0.}
changes nothing.
Am I creating the struct the wrong way or is a really common issue C and I'm just blind?
here my goal is not only to initalise the array, but also accessing the data and modifing/passing into function after the creation.
It's because after the line cam
is defined, subsequent "assignments" are no longer initializations .
To initialize an instance, you must put the "assignment" at the same place where it's defined:
Camera cam = { {.5, 1., 0.} };
or specifying member:
Camera cam = { .eye = {.5, 1., 0.} };
Note that this will also automatically zero-initialize cam.target
as no initial values are specified for it.
The error you get is obvious, type of vec3
is float [3]
- array type and you certainly cannot "assign" to array types.
You can use the initialization as mentioned by iBug in another answer. However, with a small trick , you'll be able to use the assignment, also. This would need the usage of a pointer and compound literal .
You need to change the typedef
to vec3
typedef float* vec3;
so as to make it a float *
and then, you can use compound literal to assign the values, like
cam.eye = (float [3]){ .5, 1., 0. };
cam.target = (float [3]){ .45, 2.5, 0.9 }; // just some other values.
The primary benefit of using this approach is, you are not limited to only "initialization", you can perform the assignment at any time.
PS - Compound literals are modifiable , so you do not lose any operation capabilities.
PPS
Quoting C11
, chapter §6.5.2.5/ P12
"/tmp/fileXXXXXX" (char []){"/tmp/fileXXXXXX"} (const char []){"/tmp/fileXXXXXX"}
The first always has static storage duration and has type array of char, but need not be modifiable; the last two have automatic storage duration when they occur within the body of a function, and the first of these two is modifiable.
I personally prefer more "descriptive" initialization - I like members to be specified - the code is easier to read for humans.
typedef float vec3[3];
typedef struct Cameras {
vec3 eye;
vec3 target;
} Camera;
Camera c =
{
.eye = {1.0, 2.0, 3.0},
.target = {4.0, 5.0, 6.0},
};
Camera c1 =
{
.target = {4.0, 5.0, 6.0},
};
Camera c2 =
{
.eye = {1.0, 2.0, 3.0},
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.