Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Some partial answers and answers to related questions:</p> <p>If the function in question is supposed to return a floating point type, the test is easy:</p> <pre><code>#define HAS_PROTO_FP_RET_1_ARG(f) !!((1?1:(f)(0))/2) </code></pre> <p>The 1 gets promoted to a floating point type if and only if <code>f</code> is declared to return a floating point type, and division by 2 results in a nonzero value if and only if 1 has floating point type.</p> <p>This test could be useful for checking for the presence of C99 math functions.</p> <p>With pointers, the expression <code>(1?0:(f)(0))</code> is potentially useful - it evaluates to either <code>0</code> (an <code>int</code>) or <code>(void *)0)</code> (a null pointer constant) depending on the return type of <code>f</code>. But I have yet to find any devious way to test whether an expression has integer or pointer type.</p> <p>The big problem I'm running into is that <code>void *</code> cannot participate in pointer arithmetic and does not implicitly convert to other pointer types in arithmetic contexts. For example, if it did, this would work (slightly breaking my rules about UB/IDB too):</p> <pre><code>#define HAS_PROTO_PTR_RET_1_ARG(f) ((int)((char (*)[2])2 - (1?0:(f)(0))) == 1) </code></pre> <p>Any ideas for getting around this problem?</p> <p><strong>Update:</strong> I have a solution that depends on nothing more than <code>intmax_t</code> being larger than <code>int</code>:</p> <pre><code>#define HAS_PROTO_PTR_RET_1_ARG(f) ( \ sizeof(int)!=sizeof(void *) ? sizeof ((f)(0)) == sizeof(void *) : \ sizeof (1?(intmax_t)0:(f)(0)) == sizeof(void *) ) </code></pre> <p>There are two cases. If <code>int</code> and <code>void *</code> have different sizes, we simply check the size of the return value. Otherwise, <code>int</code> and <code>void *</code> are the same size, so (by the big assumption) <code>intmax_t</code> and <code>void *</code> are not the same size. We construct an expression whose type is <code>intmax_t</code> if the return type is <code>int</code>, and <code>void *</code> if the return type is <code>void *</code>, and test its size.</p> <p>This macro fails only on machines where <code>int</code>, <code>intmax_t</code>, and <code>void *</code> all have the same size. Practically speaking, that means only on DSPs with 64-bit or larger <code>int</code>. Since pretty much all real POSIX and POSIX-like systems have fixed-size 32-bit int and <code>intmax_t</code> is required to be at least 64-bit, this is portable enough to make me happy.</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