简体   繁体   中英

Typecasting an array to pointer?

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.

What your code actually does

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.

An array is not a pointer. An array has a base pointer. But anyway, the most applicable data structure for what you are trying to achieve would be something like:

struct{
    float x;
    float y;
    float z;
} myFloat3;

Arrays are handy for variable length structures and stuff, but not the most efficient choice since you KNOW you have 3 floats and you can exploit that. Lets the compiler pack lots of your structure efficiently, and allocate from the heap just what you need.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM