假设一个人使用
typedef
来别名数据类型。
例如:
typedef int signed_integer;
typedef unsigned int unsigned_integer;
但是,通过预处理器宏,
signed_integer
和 unsigned_integer
可以分别作为其他整数类型及其无符号对应物(除了 int
和 unsigned int
)的别名。例如:
#define INTEGER_TYPE (3)
#define SHORT (1)
#define INT (2)
#define LONG (3)
#if INTEGER_TYPE == SHORT
typedef short signed_integer;
typedef unsigned short unsigned_integer;
#elif INTEGER_TYPE == INT
typedef int signed_integer;
typedef unsigned int unsigned_integer;
#elif INTEGER_TYPE == LONG
typedef long signed_integer;
typedef unsigned long unsigned_integer;
#endif
在上面的例子中,别名是
long
和unsigned long
。
我的问题是,如果有什么方法可以在运行时知道别名的别名是什么数据类型(假设宏的无知)? 有没有办法从 signed_integer
到指示 long
的东西上面的例子,或者 short
或 int
如果这个例子被重新用于后两个?
如果我知道定义逻辑编译的宏,我可以很容易地在预处理器时做出决定,不幸的是,对我来说,我正在使用的库并没有使这一点显而易见。如果我知道宏,我可以这样写:
const char* IntegerTypeString(){
#if INTEGER_TYPE == SHORT
return "short";
#elif INTEGER_TYPE == INT
return "int";
#elif INTEGER_TYPE == LONG
return "long";
#endif
}
您可以使用
_Generic
来测试类型:
typedef int Type;
#define Type char
int main(void)
{
_Static_assert(
_Generic((Type) {0}, int: 1, default: 0),
"Somebody screwed with Type.");
}
(Type) {0}
是一个复合文字,它创建一个类型为 Type
的对象。其中的 0
需要是所需类型的有效初始值设定项。
_Generic
剥离限定符(它使用类型就好像它已经进行了左值转换),因此这不会检测到添加限定符的更改,例如将 int
更改为 const int
。它还应用数组到指针的转换和函数到指针的转换。
请注意,每个枚举类型都与某些整数类型兼容,因此它不会检测它们之间的变化。