<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hi Matt,</p>
<p>if you mix A_FLOAT / A_DEFFLOAT and A_SYM / A_DEFSYM in any Pd
method definition (not just the "new" method!), the arguments are
rearranged so that in the actual C function signature all the
symbol arguments come first. <br>
</p>
<p>Here's an especially confusing example:<br>
</p>
<div class="gmail_default"><font face="monospace">foo_class =
class_new(s, (t_newmethod)foo_new, (t_method)foo_free,<br>
sizeof(t_foo), 0, A_DEFFLOAT, A_DEFSYM, A_DEFFLOAT,
A_DEFSYM, 0);</font><br>
</div>
<div class="gmail_default" style="font-family:verdana,sans-serif"><br>
</div>
<div class="gmail_default" style="font-family:verdana,sans-serif">
<div class="gmail_default"><font size="-1">becomes</font></div>
<div class="gmail_default" style="font-family:verdana,sans-serif"><br>
</div>
<div class="gmail_default"><font face="monospace">static void
*foo_new(t_symbol *arg2, t_symbol *arg4, t_floatarg arg1,
t_float arg3);</font></div>
<div class="gmail_default"><br>
<blockquote type="cite">We ended up using A_GIMME,</blockquote>
<font size="-1"><br>
</font></div>
<div class="gmail_default"><font size="-1">Good choice :-) My
personal advice: if you need to mix different argument types,
better use A_GIMME.</font></div>
<div class="gmail_default"><font size="-1"> </font></div>
<div class="gmail_default"><font size="-1"><br>
</font></div>
<div class="gmail_default"><font size="-1">---</font></div>
<div class="gmail_default"><font size="-1"><br>
</font></div>
<div class="gmail_default"><font size="-1">Technical explanation:
Pd methods take max. 5 type checked arguments. Without the
optimization, there would be 32 possible function prototypes.
Pd would not only have to declare them all, but also select
the correct one at runtime, which would be very inefficient.
With the optimization there are only 6 prototypes and you can
simply select the appropriate one based on the number of
symbol resp. gpointer arguments.<br>
</font></div>
<div class="gmail_default"><font size="-1"><br>
</font></div>
<div class="gmail_default"><font size="-1">If you want to learn
more, have a look at pd_typedmess() in in m_class.c.</font></div>
<div class="gmail_default"><font size="-1"><br>
</font></div>
<div class="gmail_default"><font size="-1">Fun fact: </font><font
size="-1"><font size="-1">pd_typedmess()</font> often calls
function pointers with more arguments than the original
functions - which is undefined behavior. It just happens to
work because in the default calling convention ("cdecl") the
caller cleans up the stack. With other calling conventions
where the *callee* has to clean up the stack, e. g. "stdcall",
this would lead to stack corruption and crash horribly :-)<br>
</font></div>
<div class="gmail_default"><font size="-1"><br>
</font></div>
<div class="gmail_default"><font size="-1">Christof</font><br>
</div>
</div>
<div class="gmail_default" style="font-family:verdana,sans-serif"><br>
</div>
<div class="moz-cite-prefix">On 05.08.2021 20:22, Matt Barber wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CAOrke7F-iRv_Y=G_NGs=1qaix1__Xs-zgwmkJp8HsYo0URyt7A@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<div dir="auto">
<div class="gmail_quote" dir="auto">
<div dir="ltr" class="gmail_attr"><span
style="font-family:verdana,sans-serif">Hi dev list,</span></div>
<div dir="ltr">
<div class="gmail_default"
style="font-family:verdana,sans-serif"><br>
</div>
<div class="gmail_default"
style="font-family:verdana,sans-serif">Question about the
syntax of creation arguments and type checking. I was
working on an object yesterday, with the following setup
line:</div>
<div class="gmail_default"
style="font-family:verdana,sans-serif"><br>
</div>
<div class="gmail_default"><font face="monospace">grab_class
= class_new(s, (t_newmethod)grab_new,
(t_method)grab_free,<br>
sizeof(t_grab), 0, A_DEFFLOAT, A_DEFSYM, 0);</font><br>
</div>
<div class="gmail_default"
style="font-family:verdana,sans-serif"><br>
</div>
<div class="gmail_default"
style="font-family:verdana,sans-serif">I'd assumed that it
would require grab_new() to have this declaration to match
the order float, symbol as in class_new:</div>
<div class="gmail_default"
style="font-family:verdana,sans-serif"><br>
</div>
<div class="gmail_default"><font face="monospace">static
void *grab_new(t_floatarg f, t_symbol *s);</font></div>
<div class="gmail_default"
style="font-family:verdana,sans-serif"><br>
</div>
<div class="gmail_default"
style="font-family:verdana,sans-serif">but it only worked
with the reverse:</div>
<div class="gmail_default"
style="font-family:verdana,sans-serif"><br>
</div>
<div class="gmail_default"><font face="monospace">static
void *grab_new(t_symbol *s, t_floatarg f);</font><br>
</div>
<div class="gmail_default"
style="font-family:verdana,sans-serif"><br>
</div>
<div class="gmail_default"
style="font-family:verdana,sans-serif">We ended up using
A_GIMME, but for the future, is there a way to know the
order of parameters passed to the creator?</div>
<div class="gmail_default"
style="font-family:verdana,sans-serif"><br>
</div>
<div class="gmail_default"
style="font-family:verdana,sans-serif">Thanks,</div>
<div class="gmail_default"
style="font-family:verdana,sans-serif">Matt<br>
</div>
</div>
</div>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<pre class="moz-quote-pre" wrap="">_______________________________________________
Pd-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Pd-dev@lists.iem.at">Pd-dev@lists.iem.at</a>
<a class="moz-txt-link-freetext" href="https://lists.puredata.info/listinfo/pd-dev">https://lists.puredata.info/listinfo/pd-dev</a>
</pre>
</blockquote>
</body>
</html>