Ben Bacarisse
7/15/2011 6:27:00 PM
"Joel C. Salomon" <joelcsalomon@gmail.com> writes:
> On 07/15/2011 06:40 AM, Ben Bacarisse wrote:
>> "Joel C. Salomon" <joelcsalomon@gmail.com> writes:
>>> In another forum, we're dealing with functions that can usefully be made
>>> <tgmath.h>-like generic, but for which mixing types is meaningless. I
>>> suggested that, given the prototypes
>>>
>>> int totalorder(double x, double y);
>>> int totalorderf(float x, float y);
>>>
>>> we could use the C1x keyword _Generic to define a macro totalorder(x,y)
>>> for which
>>> * totalorder(1.0, 2.0) => (totalorder)(1.0, 2.0)
>>> * totalorder(1.0f, 2.0f) => (totalorderf)(1.0f, 2.0f)
>>> * totalorder(1.0, 2.0f) => compile error
>>> * totalorder(1.0f, 2.0) => compile error
>>>
>>> The most obvious method of yielding a compile error in C1x is
>>> _Static_assert, so we tried this:
>>>
>>> #define totalorder(x,y) \
>>> _Generic((x), \
>>> float: _Generic((y), \
>>> float: totalorderf, \
>>> double: _Static_assert(0, "type mismatch")), \
>>> double: _Generic((y), \
>>> float: _Static_assert(0, "type mismatch")), \
>>> double: totalorder))((x),(y))
>>>
>>> The trouble is that _Generic expands to an expression, which
>>> _Static_assert is not. So, to recap my question, is there some sort of
>>> legal expression I can use that will allow the "good" generic selection
>>> to work while producing an error -- almost any error will do -- on the
>>> "bad" paths?
>>
>> I'll suggest another tack. Why not just remove the option of the "bad"
>> types in the inner _Generic expressions? A type for y that is not
>> compatible with the only listed option is a constraint violation so a
>> diagnostic is required.
>
> Because .... Hmm, are you suggesting something like
>
> #define totalorder(x,y) \
> _Generic((x), \
> float: _Generic((y), float: totalorderf), \
> double: _Generic((y), double: totalorder)) ((x),(y))
>
> instead?
Exactly.
> That should catch usages like
>
> totalorder(1.0f, 2.0)
>
> but will it catch
>
> totalorder(1.0, 2.0f)
>
> as well?
I don't see why not. In the second case, 1.0 is of type double and 2.0f
id not so the inner _Generic has be a constraint violation.
> Is there a compiler under which I can test this?
The online clang documentation talked about it but my installed version
does not seem to understand them.
--
Ben.