5

I have the following 2 typedef's:

typedef float matrix_3x4[3][4];
typedef matrix_3x4 bone_mat[128];

And the following function definition:

float ****get_bones();

Why is the following code giving me a type conversion error?

bone_mat *mat = get_bones();

Error:

error: cannot convert ‘float ****’ to ‘float (*)[128][3][4]’ in initialization
   85 |     bone_mat *mat = get_bones();
      |                     ~~~~~~~~~^~
      |                              |
      |                              float****

Tried changing the type of mat to bone_mat or bone_mat**, but shouldn't float(*)[128][3][4] be the same as float****?

Casting the return value of the function to (bone_mat*) doesn't work either.

9
  • 3
    Not an answer, but once you get beyond more than 2 levels of indirection, consider changing your types to nested structures and arrays thereof. It's hard to reason about a float ****. Commented Jul 28, 2023 at 20:42
  • 4
    Important note: ARRAYS ARE NOT POINTERS. Commented Jul 28, 2023 at 20:45
  • 2
    It may be surprising but float**** is not a 4d array. Commented Jul 28, 2023 at 20:48
  • 2
    No. Because dimensions of an array object are a bound its type. The float**** has no dimensions information in it thus it is not a pointer to array even though it admits ptr[a][b][c][d] syntax Commented Jul 28, 2023 at 20:55
  • 2
    @trxgnyp1 Do you have access to the source code of get_bones()? If so, can you post it? Commented Jul 28, 2023 at 21:12

1 Answer 1

2

A pointer is not an array. A pointer can point to an element of an array. float **** is a pointer to a pointer to a pointer to a pointer to float, a very unlikely object to come across in a real life project.

mat is a pointer to a bone_mat which itself is an array or 128 arrays of 3 arrays of 4 floats, a very different type of beast.

Should you post the source code to get_bones(), I would be surprised if it returns an actual float ****, I would bet it allocates memory for a bone_mat and converts the object pointer to a type inconsistent with the allocation size and block usage.

Quoting Brian61354270:

Think about the memory and addresses involved. float*** * is a pointer to a float***. That means that when you dereference a float****, you arrive at a location in memory that contains a float***. Not a float, but a pointer to another pointer. Dereference that pointer, and you arrive to a location that contains a float**, Still not a float, but another pointer to a pointer. I could keep going. Contrast that with float (*)[128][3][4], which is a pointer to a chunk of memory with 128 * 3 * 4 contiguous floats.

Sign up to request clarification or add additional context in comments.

1 Comment

I do not have the source code of the function, only the definition. I am marking the answer as valid, but Brian61354270's comment explained way better.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.