1

I have a function(in some library) whose signature is this:

extern LIB3DSAPI void lib3ds_mesh_calculate_face_normals(Lib3dsMesh *mesh, float (*face_normals)[3]);

what does it expect in second argument?

I tried this:

        float   *norm_verts[3];
        norm_verts=(float(*)[3])malloc(3*sizeof(float[3])*mesh->nfaces);
        lib3ds_mesh_calculate_face_normals(mesh, norm_faces);

on the second line, it says Expression must be modifiable value and the third line says argument of type float** is incompatible with parameter of type float(*)[3]

My intuition was that float* [3] is just 3 pointers but why the hell is the * wrapped in brackets?

3
  • 1
    Hint: in Linux there are nifty cdecl and uncdecl tools for encoding and decoding cryptic C definitions to plain english. Commented Oct 26, 2012 at 14:37
  • I was just wondering, if this function computes the normals of the mesh, wouldn't you need an array with the same size as the number of faces in the mesh ? Commented Oct 26, 2012 at 14:53
  • @mux:ok, Yeah sorry, lib3ds_mesh_calculate_face_normals calculates normals per face which would need an array of same size and there's another function to calculate per vertex normals which takes an array thrice as big. So I messed up while copying the code..:) Commented Oct 26, 2012 at 15:44

3 Answers 3

2
float (*face_normals)[3] // face_normals is a pointer (to an array of 3 floats)
float *norm_verts[3];    // norm_verts is an array of 3 pointers (to float)

Pointers are not arrays, arrays are not pointers. I suggest you read comp.lang.c FAQ, starting with section 6.

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

Comments

1

The * is wrapped in brackets to give it tighter binding. The 2nd arg to lib3ds_mesh_calculate_face_normals is read "face_normals is a pointer to an array of 3 float`.

Try:

float   (*norm_verts)[3];
norm_verts=(float(*)[3])malloc(sizeof(*norm_verts)*mesh->nfaces);
lib3ds_mesh_calculate_face_normals(mesh, norm_vets);

Comments

1

My intuition was that float* [3] is just 3 pointers

It is.

It's also not what the code says.

The function is asking for a pointer to an array of three floats. The parentheses make sure that it is parsed that way by "binding" the * to the name and not the type.

Lib3dsMesh *mesh    = getMeshFromSomewhere();
float norm_faces[3] = {};

lib3ds_mesh_calculate_face_normals(mesh, &norm_faces);

In this manner, the function lib3ds_mesh_calculate_face_normals knows that it is dealing with the original, actual array norm_faces and not some copy and not some name decayed to a pointer without dimension information.

This is the way to do "out" arguments with arrays without having to pass a float* and a separate length argument.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.