really easy max SDK (or perhaps C) question about void function parameters

derp mcderpington's icon

I'm just now starting to dive into Max SDK development, and my C is a little rusty.
I understand in C you can use the void keyword to state "no parameters" but what's happening here is slightly different.

I'm reading through the max API about linked lists at
https://cycling74.com/sdk/MaxSDK-5.1.1/html/chapter_datastructures.html
and see, for example, this:

the function call:
linklist_sort(list, (t_cmpfn)mysortfun);

the function:
//the line in question
long mysortfun(void *a, void *b)
{
t_symbol *sa = (t_symbol *)a;
t_symbol *sb = (t_symbol *)b;

return strcmp(sa->s_name, sb->s_name) > 0;
}

why does mysortfun take void parameters? and, where is it getting the pointers *a and *b?

Emmanuel Jourdan's icon

It's just to have a generic signature, so you can cast it to whatever the real type of the thing is. A t_symbol* in your case, which is a Max type to store a "string" and/or a pointer to an object.

Peter Castine's icon

Just to further explicate… a pointer-to-void (void*) is different from just plain void. C uses a pointer to void to mean "pointer to something, but at this point in the code it's not possible for the compiler (or the calling function) to know exactly what datatype the pointer is pointing to".

Since pointers always have the same size, saying (void*) tells the compiler how much space it needs to reserve on the stack for a function call, but disables any typechecking that it might otherwise do. That does mean that *you* have to be careful that when you say something like

t_symbol *sa = (t_symbol *)a;

that a really is a pointer to a t_symbol.

Hope this helps.

derp mcderpington's icon

Thanks e and Peter- that helped a lot. following the same linked list example, i have another question.

in this line:

index = linklist_findfirst(list, &found, mysearchfun, gensym("four")); // find the "four" symbol

I'm a bit confused about the use/meaning of the &found argument.
is it an internally defined linklist traversal pointer for the function?

shouldn't there be a "void* found" defined previously before the function call? (is that an error?)

or, does it not need one because internally linklist_findfirst()'s second parameter is of type void** o (generic sig of a pointer to a pointer?)

/boggle.

Peter Castine's icon

You're right that found isn't declared in the sample code, and that would cause a compiler error.

Note, however, that in this particular bit of sample code, the declaration would probably be

t_symbol* found;

One of the things about a function prototype that uses void* is that it will accept a pointer to anything. K&RII uses the term "generic pointer," which is a pretty good way of thinking about it.

You might want to spend a bit of time with K&RII Chapter 5, which goes into all the gory details of what you can and cannot do with generic pointers, as well as taking addresses, [ab]using pointer as arrays (and vice-versa), and where typecasts can be implicit or where they need to be explicit.

Guaranteed cure for insomnia;-)

derp mcderpington's icon

ahh right that makes sense that it needs a t_symbol. glad to hear im not crazy. good call on the K&R book, i'll take a look when i'm trying to fall asleep, thanks!