Is it possible to un-const typeof in gcc pure C?
This is a rather late answer, but if you don't mind using more GCC extensions you can do this like this (building upon a previous answer somewhat).
#define UNCONST_HAX_(TYPE) ({TYPE _tmp_macro_var_; _tmp_macro_var_;})
#define UNCONST(x) \
__typeof__(_Generic((x), \
signed char: UNCONST_HAX_(signed char), \
const signed char: UNCONST_HAX_(signed char), \
unsigned char: UNCONST_HAX_(unsigned char), \
const unsigned char: UNCONST_HAX_(unsigned char), \
short: UNCONST_HAX_(short), \
const short: UNCONST_HAX_(short), \
unsigned short: UNCONST_HAX_(unsigned short), \
const unsigned short: UNCONST_HAX_(unsigned short), \
int: UNCONST_HAX_(int), \
const int: UNCONST_HAX_(int), \
unsigned: UNCONST_HAX_(unsigned), \
const unsigned: UNCONST_HAX_(unsigned), \
long: UNCONST_HAX_(long), \
const long: UNCONST_HAX_(long), \
unsigned long: UNCONST_HAX_(unsigned long), \
const unsigned long: UNCONST_HAX_(unsigned long), \
long long: UNCONST_HAX_(long long), \
const long long: UNCONST_HAX_(long long), \
unsigned long long: UNCONST_HAX_(unsigned long long), \
const unsigned long long: UNCONST_HAX_(unsigned long long), \
float: UNCONST_HAX_(float), \
const float: UNCONST_HAX_(float), \
double: UNCONST_HAX_(double), \
const double: UNCONST_HAX_(double), \
long double: UNCONST_HAX_(long double), \
const long double: UNCONST_HAX_(long double) \
))
And it could be used as follows:
#define DECR(x) ({UNCONST(x) y; y = x; y--; y;})
Yes, it is pretty ugly.
If you don't mind the possible arithmetic promotion you can do this:
#define DECR(x) ({typeof(x + 0) y; y = x; y--; y;})
The trick is that the expression for typeof
is x + 0
, which is a r-value, and so the l-value-constness (which is what you want to avoid) is lost.
The same trick can be done with 1 * x
, but curiously enough, +x
and -x
don't work.