<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>