Is is possible to typedef an array?
I have a set of vector function which all accept a pointer to a float which is an array of three floats. I can typedef float* vec3_t, however it will not let me create an object by simply setting it equal to an array in brackets.
typedef float* vec3_t;
vec3_t a = {1,1,1}; // Does not work
vec3_t b = (float[]){1,1,1}; // Works
float c[] = {1,1,1}; // Works
void f(vec3_t x);
f({1,1,1}); // Error
f((float[]){1,1,1}; // OK
Could someone please explain why this works this way?
A pointer and an array are not the same thing. While they often behave in the same way, there are major differences, one of which you have just discovered.
I have substituted the typedefed type with real type, to make the explaination clearer.
float c[] = {1,1,1};
You have simply created and initialized an array
f({1,1,1});
The code above is neither a lvalue nor rvalue. The {val1,...,valn}
syntax is nothing more than an initializer and can not be used elsewehere.
float* b = (float[]){1,1,1};
In here you have created and initialized an array and then stored it's location in a pointer.
f((float[]){1,1,1};
This case is the same as the one above, but instead of storing the pointer you pass it as an argument to a function.
float* a = {1,1,1};
You are attempting to write three variables to a memory location that is not allocated yet.
In general, {valn,...,valn}
, is an initializer. At this moment you have nothing to initialize. Hence this syntax is invalid. You are trying to pour gas into a canister that has not yet been manufactured.
While I understand what you wanted to achieve, you seem to be missunderstanding the whole concept of memory and pointers. Imagine this code, which (in some dirty logic) is an equivalent of what you're trying to do:
float* a = NULL;
a[0] = 1;
a[1] = 1;
a[2] = 1;
What would happen if you executed this code?
So now you know why the compiler forbids it.
You have to many different features piled into your code, so it is not exactly clear what you mean by "why this works this way". What's "this" specifically?
Anyway, in order to "typedef an array" you have to typedef an array, not pointer
typedef float vec3_t[3];
after which you will be able to do
vec3_t a = { 1, 1, 1 };
The rest of your code has nothing to do with typedefing an array. You simply discovered the compound literal syntax, which goes as (non-scalar-type) { initializers }
and creates a nameless temporary object of the given type. The (non-scalar-type)
part is an important part of compound literal syntax. You can't omit it.
So, instead of doing
vec3_t a = { 1, 1, 1 };
f(a);
if you don't care to have a named array object a
, you can simply do
f((vec3_t) { 1, 1, 1 });
or
f((float [3]) { 1, 1, 1 });
or
f((float []) { 1, 1, 1 });
with the same effect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With