J
Joel C. Salomon
TL;DR: Is there a construct in C that will work something vaguely like
C1x's _Static_assert, but which yields an expression?
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?
Thanks,
--Joel
C1x's _Static_assert, but which yields an expression?
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?
Thanks,
--Joel