<p>Am 30.06.2012 12:50 schrieb "Bernd" <<a href="mailto:prof7bit@gmail.com">prof7bit@gmail.com</a>>:<br>
><br>
> 2012/6/30 Sven Barth <<a href="mailto:pascaldragon@googlemail.com">pascaldragon@googlemail.com</a>>:<br>
><br>
> > Your explanation is very nice and mostly correct, but in case of external<br>
> > cdecl functions in FPC the "varargs" modifier and a "array of const"<br>
> > parameter imply the same C compatible parameter passing in the compiler. See<br>
> > also here:<br>
> > <a href="http://freepascal.org/docs-html/ref/refsu77.html#x180-19000014.9.17">http://freepascal.org/docs-html/ref/refsu77.html#x180-19000014.9.17</a><br>
> ><br>
> > The only difference is when calling the functions. E.g.:<br>
> ><br>
> > procedure a(args: array of const); cdecl; external;<br>
> > procedure b; cdecl; varargs; external;<br>
> ><br>
> > begin<br>
> >   a([1, 'foo', somevar]);<br>
> >   b(1, 'foo', somevar);<br>
> > end.<br>
><br>
> This means in my case I declared the external function correctly and<br>
> only need to pass<br>
> [nil]<br>
> to make it a null terminated list? Because I tried this last night and<br>
> looked at the generated assembler and if I for example call it with<br>
><br>
>   purple_prpl_got_user_status(@self, Pointer(AName),<br>
> Pointer(AStatusID), [1,2,3,nil]);<br>
><br>
> then it will generate the following code:<br>
><br>
> 0162EF17 6a00                     push   $0x0<br>
> 0162EF19 6a03                     push   $0x3<br>
> 0162EF1B 6a02                     push   $0x2<br>
> 0162EF1D 6a01                     push   $0x1<br>
> 0162EF1F ff75f8                   pushl  -0x8(%ebp)<br>
> 0162EF22 ff75fc                   pushl  -0x4(%ebp)<br>
> 0162EF25 8b45f4                   mov    -0xc(%ebp),%eax<br>
> 0162EF28 50                       push   %eax<br>
> 0162EF29 e8b20afaff               call   0x15cf9e0<br>
> <purple_prpl_got_user_status@plt><br>
><br>
> so its just just pushing the contents of the list onto the stack as<br>
> they are and If I pass [] there would be nothing pushed at all, so the<br>
> right thing for me to do in this case would be to call it with<br>
><br>
>   purple_prpl_got_user_status(@self, Pointer(AName), Pointer(AStatusID), [nil]);<br>
><br>
> 0162EF17 6a00                     push   $0x0<br>
> 0162EF19 ff75f8                   pushl  -0x8(%ebp)<br>
> 0162EF1C ff75fc                   pushl  -0x4(%ebp)<br>
> 0162EF1F 8b45f4                   mov    -0xc(%ebp),%eax<br>
> 0162EF22 50                       push   %eax<br>
> 0162EF23 e8b80afaff               call   0x15cf9e0<br>
> <purple_prpl_got_user_status@plt><br>
><br>
> so that it will push exactly one zero onto the stack, so it gets what<br>
> it wants (an empty null-terminated list)? Then my only mistake was to<br>
> assume that [] would automatically generate a null terminated list<br>
> (for automagic[TM]  C-friendlyness) just like strings do?</p>
<p>I have now looked at your mail again. Normally you don't need to explicitly pass a "Nil" (whatever of the earlier mentioned variants you chose) as e.g. for printf the following works:</p>
<p>printf("%d %d %d", 1, 2, 3);</p>
<p>or</p>
<p>printf("%d %d %d", [1, 2, 3]);</p>
<p>(depending on the declaration)</p>
<p>But the comment above the original C function you mentioned in your initial mail explicitly states that you must pass a Null-terminated list, which the compiler doesn't do by itself. Maybe that is told to GCC by the G_GNUC_NULL_TERMINATED define (whatever it resolves to...)</p>

<p>Nevertheless passing a Nil at the end should be the correct approach in your specific case.</p>
<p>Regards,<br>
Sven</p>