<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Help with C function pointers</title>
		<link>http://www.allegro.cc/forums/view/618555</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Sat, 30 Oct 2021 23:59:20 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I have some code in my project that uses C function pointers and it&#39;s being built with <i>gcc</i> on Linux. Consider the following sample code; I&#39;m trying to understand why the first call to <span class="source-code">my_function<span class="k2">(</span><span class="k2">)</span></span> won&#39;t work but the second does:</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="p">#include &lt;stdio.h&gt;</span>
<span class="number">  2</span>
<span class="number">  3</span><span class="k1">float</span> dummy_function<span class="k2">(</span><span class="k1">float</span> f<span class="k2">)</span> <span class="k2">{</span>
<span class="number">  4</span>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_624.html" target="_blank">printf</a><span class="k2">(</span><span class="s">"Argument value:\t%.10lf\n"</span>, f<span class="k2">)</span><span class="k2">;</span>
<span class="number">  5</span>    <span class="k1">return</span> f <span class="k3">*</span> <span class="n">2</span><span class="k2">;</span>
<span class="number">  6</span><span class="k2">}</span>
<span class="number">  7</span>
<span class="number">  8</span><span class="k1">float</span> dummy_function2<span class="k2">(</span><span class="k1">float</span> <span class="k3">*</span>f<span class="k2">)</span> <span class="k2">{</span>
<span class="number">  9</span>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_624.html" target="_blank">printf</a><span class="k2">(</span><span class="s">"Argument value:\t%.10lf\n"</span>, <span class="k3">*</span>f<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 10</span>    <span class="k1">return</span> <span class="k3">*</span>f <span class="k3">*</span> <span class="n">2</span><span class="k2">;</span>
<span class="number"> 11</span><span class="k2">}</span>
<span class="number"> 12</span>
<span class="number"> 13</span><span class="k1">int</span> main<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 14</span>    <span class="k1">float</span> f <span class="k3">=</span> <span class="n">3</span>.<span class="n">1416</span><span class="k2">;</span>
<div class="highlight"><span class="number"> 15</span>    <span class="k1">float</span> <span class="k2">(</span><span class="k3">*</span>my_function<span class="k2">)</span><span class="k2">(</span><span class="k2">)</span> <span class="k3">=</span> dummy_function<span class="k2">;</span> </div><div class="highlight"><span class="number"> 16</span>    my_function<span class="k2">(</span>f<span class="k2">)</span><span class="k2">;</span> </div><div class="highlight"><span class="number"> 17</span>    my_function <span class="k3">=</span> dummy_function2<span class="k2">;</span> </div><div class="highlight"><span class="number"> 18</span>    my_function<span class="k2">(</span><span class="k3">&amp;</span>f<span class="k2">)</span><span class="k2">;</span> </div><span class="number"> 19</span><span class="k2">}</span>
</div></div><p>

The output for this code is the following:
</p><pre class="terminal">Argument value:	0.0000000000
Argument value:	3.1415998936</pre><p>

I&#39;m aware that using the correct function signature as in:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> main<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span>
    <span class="k1">float</span> f <span class="k3">=</span> <span class="n">3</span>.<span class="n">1416</span><span class="k2">;</span>
    <span class="k1">float</span> <span class="k2">(</span><span class="k3">*</span>my_function<span class="k2">)</span><span class="k2">(</span><span class="k1">float</span><span class="k2">)</span> <span class="k3">=</span> dummy_function<span class="k2">;</span>
    my_function<span class="k2">(</span>f<span class="k2">)</span><span class="k2">;</span>
    <span class="k1">float</span> <span class="k2">(</span><span class="k3">*</span>my_function2<span class="k2">)</span><span class="k2">(</span><span class="k1">float</span> <span class="k3">*</span><span class="k2">)</span> <span class="k3">=</span> dummy_function2<span class="k2">;</span>
    my_function2<span class="k2">(</span><span class="k3">&amp;</span>f<span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

will make the code work as expected but I&#39;m curious as to why the first form doesn&#39;t work. I thought declaring a function with an empty argument list meant you could call that function with an arbitrary number of arguments of any type.</p><p>Thanks.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (kenmasters1976)</author>
		<pubDate>Wed, 27 Oct 2021 08:27:32 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/618555/1051172#target">kenmasters1976</a> said:</div><div class="quote"><p>
 I thought declaring a function with an empty argument list meant you could call that function with an arbitrary number of arguments of any type.
</p></div></div><p>
Don&#39;t you mean a variac function? <img src="http://www.allegro.cc/forums/smileys/huh.gif" alt="???" /> </p><p>[edit] So the key problem you&#39;re saying, is you can&#39;t reassign the function pointer to a function with a different type signature, and then use it using the correct-for-that-new-function arguments?</p><p>Recasting a function pointer is pretty evil and undefined behavior.</p><p><a href="https://stackoverflow.com/questions/559581/casting-a-function-pointer-to-another-type">https://stackoverflow.com/questions/559581/casting-a-function-pointer-to-another-type</a></p><p><a href="https://stackoverflow.com/questions/16770690/function-pointer-to-different-functions-with-different-arguments-in-c">https://stackoverflow.com/questions/16770690/function-pointer-to-different-functions-with-different-arguments-in-c</a></p><p>I would &quot;assume&quot; that it&#39;s because the function call itself involves setup assembly that has to match the receiving function. Or it&#39;s just so evil that language developers thought nobody would ever do it so they didn&#39;t codify the results. So basically, the reason you get 0.000 and not an immediate segfault is because you&#39;ve been lucky and it&#39;s probably reading some uninitialized extra data area still within the current page.</p><p>The <b>solution</b> people show for c is using a union with multiple function pointers.</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">typedef</span> <span class="k1">union</span> <span class="k2">{</span>
  <span class="k1">double</span> <span class="k2">(</span><span class="k3">*</span>func_one<span class="k2">)</span><span class="k2">(</span><span class="k1">double</span> x, <span class="k1">double</span> a, <span class="k1">double</span> b, <span class="k1">double</span> c<span class="k2">)</span><span class="k2">;</span>
  <span class="k1">double</span> <span class="k2">(</span><span class="k3">*</span>func_two<span class="k2">)</span><span class="k2">(</span><span class="k1">double</span> x, <span class="k1">double</span> p<span class="k2">[</span><span class="k2">]</span>, <span class="k1">double</span> c<span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span> func_one_two<span class="k2">;</span>
</pre></div></div><p>

Then again, you can be super evil and probably get yours to work by recasting the function pointer ala this disgusting code:</p><div class="source-code snippet"><div class="inner"><pre>ala
    C <span class="k3">=</span> <span class="k2">(</span><span class="k2">(</span>myFunc2PtrType<span class="k2">)</span><span class="k2">(</span><span class="k3">*</span><span class="k2">(</span>myFuncPtrA<span class="k2">[</span><span class="n">1</span><span class="k2">]</span><span class="k2">)</span><span class="k2">)</span><span class="k2">)</span><span class="k2">(</span>A<span class="k2">[</span><span class="n">0</span><span class="k2">]</span>,A<span class="k2">[</span><span class="n">1</span><span class="k2">]</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

Both of those are from the linked posts.</p><p>[edit] &quot;Supposedly&quot; it&#39;s &quot;against standards, but works in the wild&quot; according to one post that says Glib uses the pattern significantly for its slots-and-signals implementation.</p><p>I was going to ask how is the compiler even letting you do your current method (without an explicit cast) because it&#39;s type violation. But apparently the compiler was warning you.
</p><div class="source-code snippet"><div class="inner"><pre>main.c:15:30: warning: initialization of <span class="k1">float</span> <span class="k2">(</span><span class="k3">*</span><span class="k2">)</span><span class="k2">(</span><span class="k2">)</span> from incompatible pointer type <span class="k1">float</span> <span class="k2">(</span><span class="k3">*</span><span class="k2">)</span><span class="k2">(</span><span class="k1">float</span><span class="k2">)</span> <span class="k2">[</span><span class="k3">-</span>Wincompatible-pointer-types<span class="k2">]</span>
   <span class="n">15</span> <span class="k3">|</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Chris Katko)</author>
		<pubDate>Wed, 27 Oct 2021 11:32:56 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/618555/1051172#target">kenmasters1976</a> said:</div><div class="quote"><p>
 I thought declaring a function with an empty argument list meant you could call that function with an arbitrary number of arguments of any type.
</p></div></div><p>

that would be elipsis (...)  like printf uses :-)<br />You&#39;ll need argumentlist macro&#39;s to use it properly va_list, va_start, va_arg and va_end.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ariesnl)</author>
		<pubDate>Wed, 27 Oct 2021 11:57:56 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/618555/1051172#target">kenmasters1976</a> said:</div><div class="quote"><p> I thought declaring a function with an empty argument list meant you could call that function with an arbitrary number of arguments of any type.</p></div></div><p>It just means &quot;ignore checking here&quot; - as CK said, it triggers a warning on newer compilers, and, just because it compiles, doesn&#39;t mean it will run correctly (this is C after all!). Also, the C standard says it&#39;s &quot;obsolescent&quot;.</p><p>See <a href="https://stackoverflow.com/questions/20835534/function-pointer-without-arguments-types">https://stackoverflow.com/questions/20835534/function-pointer-without-arguments-types</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Peter Hull)</author>
		<pubDate>Wed, 27 Oct 2021 14:20:59 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Floats are not passed on the regular stack, maybe that could explain why one works and not the other? You can make this work if you tell the compiler what the real prototype is when calling the functions, either by casting or by using a function pointer of the correct type. But you probably shouldn&#39;t be doing this anyway, unless you have some special reason.</p><p>If you want arguments of unknown types you can use void pointers or variadic functions. But you have to keep track of the actual types yourself, and not mess up. It&#39;s a risky way to program.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (torhu)</author>
		<pubDate>Wed, 27 Oct 2021 16:18:42 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thank you all for your replies, makes a lot of sense now.</p><p>The code does indeed generate a warning but I&#39;ve been using it for quite some time just &quot;because C allows it&quot;. The way I was using it was, for example, to use a <span class="source-code"><span class="k1">int</span> <span class="k2">(</span><span class="k3">*</span>my_function<span class="k2">)</span><span class="k2">(</span><span class="k2">)</span></span> variable to store a function pointer to any function that returns an <span class="source-code"><span class="k1">int</span></span> and then at some later point in the code I&#39;d call the function as in the first post. I was using this with pointers and never had an issue so I assumed it was safe to call the function this way but now I&#39;m going to start using the actual function signature; the <span class="source-code"><span class="k1">union</span></span> solution will come in handy.</p><p>Thanks.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (kenmasters1976)</author>
		<pubDate>Wed, 27 Oct 2021 18:21:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/618555/1051177#target">torhu</a> said:</div><div class="quote"><p>
 It&#39;s a risky way to program.
</p></div></div><p>
I was just thinking about that. Any time you go out of your way to <i>remove static typing</i> in a static language, you&#39;re in dangerous territory! </p><p>If you&#39;re doing that--and not doing it because some obscure commercial product requires you to do so for your day job--I&#39;d say, instead of hacking around a language, pick a more expressive language.* C++/D/C#/what-have-you. </p><p>*C is simple and that&#39;s what it&#39;s great at! </p><p>I&#39;m no C guru, but it at least seems that anytime you&#39;re using void pointers or recasting function pointers, you&#39;re breaking one of the best tools for ensuring your program is valid, the type checker. You can pass it literally anything (including junk data) and it&#39;s going to call it.</p><p>Super interesting post though! I never really thought about recasting function pointers before.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Chris Katko)</author>
		<pubDate>Thu, 28 Oct 2021 00:16:34 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>This&#39;s interesting, I did not know that in C you can freely assign the parameters even if in the declared pointer function you do not have any. This cannot be done in C++.</p><p>I have checked from gdb and I have come to the conclusion that it is a error from compiler, it would be necessary to see if other compilers work the same or work accordingly.</p><p>According to the code, in case incorporating parameters out of nowhere is valid, it should work without problems.</p><p>The function code for dummy_function for either a function pointer or a normal function is almost the same only with a slight mismatch.</p><p>For this test i add &#39;dummy_function(f);&#39; in the line 19.</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span>my_function<span class="k2">(</span>f<span class="k2">)</span><span class="k2">;</span>
<span class="number">  2</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">58</span><span class="k3">&gt;</span><span class="k2">:</span>  flds   <span class="k3">-</span><span class="n">0x14</span><span class="k2">(</span>%ebp<span class="k2">)</span>
<span class="number">  3</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">61</span><span class="k3">&gt;</span><span class="k2">:</span>  sub    $<span class="n">0x8</span>,%esp
<span class="number">  4</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">64</span><span class="k3">&gt;</span><span class="k2">:</span>  lea    <span class="k3">-</span><span class="n">0x8</span><span class="k2">(</span>%esp<span class="k2">)</span>,%esp
<span class="number">  5</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">68</span><span class="k3">&gt;</span><span class="k2">:</span>  fstpl  <span class="k2">(</span>%esp<span class="k2">)</span>
<span class="number">  6</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">71</span><span class="k3">&gt;</span><span class="k2">:</span>  mov    <span class="k3">-</span><span class="n">0x10</span><span class="k2">(</span>%ebp<span class="k2">)</span>,%eax
<span class="number">  7</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">74</span><span class="k3">&gt;</span><span class="k2">:</span>  call   <span class="k3">*</span>%eax
<span class="number">  8</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">76</span><span class="k3">&gt;</span><span class="k2">:</span>  fstp   %st<span class="k2">(</span><span class="n">0</span><span class="k2">)</span>
<span class="number">  9</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">78</span><span class="k3">&gt;</span><span class="k2">:</span>  add    $<span class="n">0x10</span>,%esp
<span class="number"> 10</span>
<span class="number"> 11</span>dummy_function<span class="k2">(</span>f<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 12</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">107</span><span class="k3">&gt;</span><span class="k2">:</span>  flds   <span class="k3">-</span><span class="n">0x14</span><span class="k2">(</span>%ebp<span class="k2">)</span>
<span class="number"> 13</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">110</span><span class="k3">&gt;</span><span class="k2">:</span>  sub    $<span class="n">0xc</span>,%esp
<span class="number"> 14</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">113</span><span class="k3">&gt;</span><span class="k2">:</span>  lea    <span class="k3">-</span><span class="n">0x4</span><span class="k2">(</span>%esp<span class="k2">)</span>,%esp
<span class="number"> 15</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">117</span><span class="k3">&gt;</span><span class="k2">:</span>  fstps  <span class="k2">(</span>%esp<span class="k2">)</span>
<span class="number"> 16</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">120</span><span class="k3">&gt;</span><span class="k2">:</span>  call   <span class="n">0x11ad</span> <span class="k3">&lt;</span>dummy_function&gt;
<span class="number"> 17</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">125</span><span class="k3">&gt;</span><span class="k2">:</span>  fstp   %st<span class="k2">(</span><span class="n">0</span><span class="k2">)</span>
<span class="number"> 18</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">127</span><span class="k3">&gt;</span><span class="k2">:</span>  add    $<span class="n">0x10</span>,%esp
<span class="number"> 19</span>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">130</span><span class="k3">&gt;</span><span class="k2">:</span>  mov    $<span class="n">0x0</span>,%eax
</div></div><p>

in 61~64 and 110~113.<br />There are really no clear instructions even with bytecodes, I must assume that &#39;flds&#39; adds the value on stack and &#39;fstpl/s&#39; retrieves a value from the stack, i judging from how it has been spread in the code, I must assume that &#39;s&#39; occupies 4 bytes (float) and &#39;l&#39; occupies 8 bytes (double).<br />then dummy_function(110~113) work fine because always work with float, instead of my_function(61~64) that load float and store double.</p><p>and now in begin of dummy_function:</p><div class="source-code snippet"><div class="inner"><pre>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">0</span><span class="k3">&gt;</span><span class="k2">:</span>  push   %ebp
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">1</span><span class="k3">&gt;</span><span class="k2">:</span>  mov    %esp,%ebp
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">3</span><span class="k3">&gt;</span><span class="k2">:</span>  push   %ebx
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">4</span><span class="k3">&gt;</span><span class="k2">:</span>  sub    $<span class="n">0x4</span>,%esp  <span class="c">// -3</span>
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">7</span><span class="k3">&gt;</span><span class="k2">:</span>  call   <span class="n">0x12c5</span> <span class="k3">&lt;</span>__x86.get_pc_thunk.ax&gt;
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">12</span><span class="k3">&gt;</span><span class="k2">:</span>  add    $<span class="n">0x2e47</span>,%eax
</pre></div></div><p>

and from printf of dummy_function, that load a float and store a double for printf:</p><div class="source-code snippet"><div class="inner"><pre>   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">17</span><span class="k3">&gt;</span><span class="k2">:</span>  flds   <span class="n">0x8</span><span class="k2">(</span>%ebp<span class="k2">)</span>  <span class="c">// +2</span>
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">20</span><span class="k3">&gt;</span><span class="k2">:</span>  sub    $<span class="n">0x4</span>,%esp
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">23</span><span class="k3">&gt;</span><span class="k2">:</span>  lea    <span class="k3">-</span><span class="n">0x8</span><span class="k2">(</span>%esp<span class="k2">)</span>,%esp  <span class="c">// -1 (-2)</span>
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">27</span><span class="k3">&gt;</span><span class="k2">:</span>  fstpl  <span class="k2">(</span>%esp<span class="k2">)</span>
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">30</span><span class="k3">&gt;</span><span class="k2">:</span>  lea    <span class="k3">-</span><span class="n">0x1ff8</span><span class="k2">(</span>%eax<span class="k2">)</span>,%edx
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">36</span><span class="k3">&gt;</span><span class="k2">:</span>  push   %edx
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">37</span><span class="k3">&gt;</span><span class="k2">:</span>  mov    %eax,%ebx
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">39</span><span class="k3">&gt;</span><span class="k2">:</span>  call   <span class="n">0x1040</span> <span class="k3">&lt;</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_624.html" target="_blank">printf</a>@plt&gt;
   <span class="k3">&lt;</span><span class="k3">+</span><span class="n">44</span><span class="k3">&gt;</span><span class="k2">:</span>  add    $<span class="n">0x10</span>,%esp
</pre></div></div><p>

0x8(%ebp) fit from a float in the 4x4 bytes added before enter in the function (___f), but not for double added before enter in the function (__ff).<br />In the function only load a float and not double, that&#39;s where cause problems and destroy the values. The memory area is always valid, but the loaded data is wrong.</p><p><b>EDIT:</b><br />It&#39;s very likely that the compiler has no way of knowing what type of variable to work with, even if &#39;float&#39; has been declared, it&#39;s disconnected between the function and the input to the function.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (RmBeer2)</author>
		<pubDate>Thu, 28 Oct 2021 21:10:09 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/618555/1051186#target">RmBeer2</a> said:</div><div class="quote"><p>This&#39;s interesting, I did not know that in C you can freely assign the parameters even if in the declared pointer function you do not have any. This cannot be done in C++.</p></div></div><p>
Technically you can, you just need to be explicit.<br /><span class="source-code"><span class="k1">float</span> <span class="k2">(</span><span class="k3">*</span>my_function<span class="k2">)</span><span class="k2">(</span>...<span class="k2">)</span></span><br />is valid in C/C++, and is equivalent to<br /><span class="source-code"><span class="k1">float</span> <span class="k2">(</span><span class="k3">*</span>my_function<span class="k2">)</span><span class="k2">(</span><span class="k2">)</span></span><br />in C. It&#39;s a variadic function, taking a series of parameters on the stack that the callee needs to pop off to use, using the varags API. The way parameters are passed over varargs can be different to how they&#39;re passed with explicit type parameters, which is why using it as a generic signature to other non-variadic functions doesn&#39;t work.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kitty Cat)</author>
		<pubDate>Sat, 30 Oct 2021 23:59:20 +0000</pubDate>
	</item>
</rss>
