<p>Am 30.06.2012 03:25 schrieb "kyan" <<a href="mailto:alfasud.ti@gmail.com">alfasud.ti@gmail.com</a>>:<br>
> A pascal open array of const which is the closest concept to a C<br>
> ellipsis may have similar semantics but its binary representation on<br>
> the parameter stack is completely different. First of all, since it<br>
> has to work in all calling conventions and not just cdecl the high<br>
> bound of passed array elements is pushed in the stack after a pointer<br>
> to an array of TVarRec structures that each contains a type attribute<br>
> and either a value or a pointer to the value of the parameter. So the<br>
> open array doesn't need to be the last parameter like the C ellipsis<br>
> and there can be more than one in a routine signature. So your<br>
> declaration of purple_prpl_got_user_status<br>
><br>
> procedure purple_prpl_got_user_status(account: PPurpleAccount;<br>
>   name_, status_id: PChar;<br>
>   par3: array of const);<br>
><br>
> is equivalent to:<br>
><br>
> procedure purple_prpl_got_user_status(account: PPurpleAccount;<br>
>   name_, status_id: PChar;<br>
>   par3: PVarRecArray; par3HighBound: Integer);<br>
><br>
> So the caller pushes only a pointer to a TVarRec array and an integer<br>
> while the function expects a continuous "stream" of parameters. If you<br>
> pass [] the compiler generates code to push a nil pointer (zero<br>
> PtrInt) and a high bound of -1. If the C function can handle these<br>
> values on the stack it *sort of* works by accident, but it will<br>
> probably fail if it tries to read past the -1 high bound for a<br>
> specific value of status_id that requires more variable parameters.</p>
<p>Your explanation is very nice and mostly correct, but in case of external cdecl functions in FPC the "varargs" modifier and a "array of const" parameter imply the same C compatible parameter passing in the compiler. See also here: <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></p>

<p>The only difference is when calling the functions. E.g.:</p>
<p>procedure a(args: array of const); cdecl; external;<br>
procedure b; cdecl; varargs; external;</p>
<p>begin<br>
  a([1, 'foo', somevar]);<br>
  b(1, 'foo', somevar);<br>
end.</p>
<p>Regards,<br>
Sven</p>