Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>There are a few pieces to this that allow all of these combinations of operators to work the same way.</p> <p>The fundamental reason why all of these work is that a function (like <code>foo</code>) is implicitly convertible to a pointer to the function. This is why <code>void (*p1_foo)() = foo;</code> works: <code>foo</code> is implicitly converted into a pointer to itself and that pointer is assigned to <code>p1_foo</code>.</p> <p>The unary <code>&amp;</code>, when applied to a function, yields a pointer to the function, just like it yields the address of an object when it is applied to an object. For pointers to ordinary functions, it is always redundant because of the implicit function-to-function-pointer conversion. In any case, this is why <code>void (*p3_foo)() = &amp;foo;</code> works.</p> <p>The unary <code>*</code>, when applied to a function pointer, yields the pointed-to function, just like it yields the pointed-to object when it is applied to an ordinary pointer to an object.</p> <p>These rules can be combined. Consider your second to last example, <code>**foo</code>: </p> <ul> <li>First, <code>foo</code> is implicitly converted to a pointer to itself and the first <code>*</code> is applied to that function pointer, yielding the function <code>foo</code> again.</li> <li>Then, the result is again implicitly converted to a pointer to itself and the second <code>*</code> is applied, again yielding the function <code>foo</code>.</li> <li>It is then implicitly converted to a function pointer again and assigned to the variable.</li> </ul> <p>You can add as many <code>*</code>s as you like, the result is always the same. The more <code>*</code>s, the merrier.</p> <p>We can also consider your fifth example, <code>&amp;*foo</code>:</p> <ul> <li>First, <code>foo</code> is implicitly converted to a pointer to itself; the unary <code>*</code> is applied, yielding <code>foo</code> again.</li> <li>Then, the <code>&amp;</code> is applied to <code>foo</code>, yielding a pointer to <code>foo</code>, which is assigned to the variable.</li> </ul> <p>The <code>&amp;</code> can only be applied to a function though, not to a function that has been converted to a function pointer (unless, of course, the function pointer is a variable, in which case the result is a pointer-to-a-pointer-to-a-function; for example, you could add to your list <code>void (**pp_foo)() = &amp;p7_foo;</code>).</p> <p>This is why <code>&amp;&amp;foo</code> doesn't work: <code>&amp;foo</code> is not a function; it is a function pointer that is an rvalue. However, <code>&amp;*&amp;*&amp;*&amp;*&amp;*&amp;*foo</code> would work, as would <code>&amp;******&amp;foo</code>, because in both of those expressions the <code>&amp;</code> is always applied to a function and not to an rvalue function pointer.</p> <p>Note also that you do not need to use the unary <code>*</code> to make the call via the function pointer; both <code>(*p1_foo)();</code> and <code>(p1_foo)();</code> have the same result, again because of the function-to-function-pointer conversion.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload