是否有可能在gcc纯C中使用un const typeof?
我有一个宏使用GCC的typeof来创建一个相同类型的宏参数的变量。 问题是:如果该参数具有const
类型,则在宏内创建的变量是const
,我不能使用它。 例如:
#include #define DECR(x) ({typeof(x) y; y = x; y--; y;}) int main(void) { const int v = 5; printf("%d\n", DECR(v)); return 0; }
汇编给出:
$ cc -c -o to tc tc: In function 'main': tc:9:2: error: assignment of read-only variable 'y' tc:9:2: error: decrement of read-only variable 'y' make: *** [to] Error 1
有没有办法复制一个值的类型和un-const呢?
如果你不介意可能的算术推广,你可以这样做:
#define DECR(x) ({typeof(x + 0) y; y = x; y--; y;})
诀窍是typeof
的表达式是x + 0
,这是一个r值,因此l-value-constness(这是你想要避免的)会丢失。
同样的技巧可以用1 * x
,但奇怪的是, +x
和-x
不起作用。
是否有可能在gcc纯C中使用un const typeof?
我不是这样,但这将有效:
#define DECR(x) __extension__({__typeof__(x) y = x - 1; y;})
请注意__extension__
用于禁用ISO C forbids braced-groups within expressions[-pedantic]
警告中的ISO C forbids braced-groups within expressions[-pedantic]
。
您可以使用C11 _Generic
选择从const
映射到非const
类型:
#define DECR_(t, x) ({ ty = (x); --y; y; }) #define DECR(x) _Generic((x), \ int: DECR_(int, (x)), \ const int: DECR_(int, (x)), \ long: DECR_(long, (x)), \ const long: DECR_(long, (x)), \ unsigned int: DECR_(unsigned int, (x)), \ const unsigned int: DECR_(unsigned int, (x)), \ long long: DECR_(long long, (x)), \ const long long: DECR_(long long, (x)))
虽然它涉及很多打字,即使你只需要覆盖整体类型。 如今,C11还远未被广泛使用。 Coliru的现场例子。
c中没有标准的方法来修改const变量或从现有变量中删除说明符。