[Cfp-interest] tgmath and macro suppression

Joel C. Salomon joelcsalomon at gmail.com
Sat Mar 24 18:22:14 PDT 2012


Jim Thomas wrote:
>
> On Mar 23, 2012, at 5:32 AM, Joel C. Salomon wrote:
>
>> Jim Thomas <jaswthomas at sbcglobal.net> wrote:
>>>
>>> What if, instead, it were
>>>
>>>   #define exp(x) _Generic((x), float:expf(x), default:exp(x))
>>>
>>> (I realize this isn't what C11 suggests.)
>>
>> That would be subject to macro expansion of expf()—in fact, there
>> would be no way to avoid this expansion—but not secondary expansion of
>> exp(), leading to an inconsistency.
>
> Please explain this in more detail.

// <math.h>
double exp(double);
float expf(float);
#define exp(x) __builtin_exp(x)
#define expf(x) __builtin_expf(x)

// <tgmath.h>, as suggested by Jim
#define exp(x) _Generic((x), \
    float: expf(x) /* macro expf(x) expands to __builtin_expf(x) */ \
    default: exp(x) /* does NOT expand to __builtin_exp(x) */ \
    )

(Actually, an “#undef exp” is needed before the macro redefinition.)

Aside from the inconsistency noted in the comments, can you give me an
invocation of exp, applied to a float, that will resolve to (expf)(f)
rather than to __builtin_expf(f)?

>> I'd suggest that the definition of type-generic macros given is
>> implicitly intended to suppress macro expansion of expf() et al.
>> within the <tgmath.h> functions.
>
> Are you referring to the definition in 7.25? I don't recall that being the intention.

Looking at the Standard, it seems you’re right; the fact that the
generic-selection example for cbrt in §6.5.1.1 ¶5 evaluates to the
function name rather than to a function call is artifact of the
discussion in N1330 & N1404, not an intention to demand macro
suppression.

But they should have intended it. :-)

—Joel



More information about the Cfp-interest mailing list