I want to write a function (or macro) that tells whether or not a variable is signed. That is, how to tell if the given variable's type is signed or not, as opposed to its value.
You could create a _Generic
macro:
#define is_signed(X) _Generic((X), \
short : true, \
int : true, \
long : true, \
long long : true, \
unsigned short : false, \
unsigned int : false, \
unsigned long : false, \
unsigned long long : false, \
float : true, \
double : true, \
long double : true \
)
You could also delegate to functions if you'd like to do something more complicated. I've made a simple example where is_signed
returns a signs
object including the signedness of both the type
and the value
of the supplied variable. I've excluded the parameter names where they are not needed, which will be allowed in the C2x standard. You can add dummy names if you want.
typedef struct { bool type; bool value; } signs;
signs Short(short x) { signs r={true, x < 0}; return r; }
signs Int(int x) { signs r={true, x < 0}; return r; }
signs Long(long x) { signs r={true, x < 0}; return r; }
signs Longlong(long long x) { signs r={true, x < 0}; return r; }
signs UShort(unsigned short) { signs r={false, false}; return r; }
signs UInt(unsigned int) { signs r={false, false}; return r; }
signs ULong(unsigned long) { signs r={false, false}; return r; }
signs ULonglong(unsigned long long) { signs r={false, false}; return r; }
signs Float(float x) { signs r={true, x < 0.f}; return r; }
signs Double(double x) { signs r={true, x < 0.}; return r; }
signs LongDouble(long double x) { signs r={true, x < 0.L}; return r; }
#define is_signed(X) _Generic((X), \
short : Short, \
int : Int, \
long : Long, \
long long : Longlong, \
unsigned short : UShort, \
unsigned int : UInt, \
unsigned long : ULong, \
unsigned long long : ULonglong, \
float : Float, \
double : Double, \
long double : LongDouble \
)(X)