比较C中的名称类型

Bob*_*ith 5 c macros

我试图以一种捕获某些错误的方式在C(唉,而不是C++)中编写宏,特别是如果我传递了错误类型的名称.

例如,用

typedef int APLNELM;
typedef int APLRANK;
#define IsScalar(a) ((a) == 0)

APLNELM AplNelm = 0;
APLRANK AplRank = 0;
Run Code Online (Sandbox Code Playgroud)

调用IsScalar (AplRank)是正确的,因为Scalar是一个Rank概念,但是IsScalar (AplNelm)错误是因为Scalar不是#elements元素的概念.

一些聪明的人可以找到一种方法来编写IsScalar宏,以便它检查传递给它的名称的类型,以确保它是类型APLRANK?如果提供解决方案,请随意以任何等效方式重写原始示例.

pab*_*977 0

如果要定义两个不同的整数类型,直接typedef方法会失败,因为typedef会为同一类型创建同义词,而不会创建新类型。

有一种方法可以创建不同的整数类型,但即使在这种情况下,也无法通过它们的值“检测”它们。

例如,观察以下代码:

 enum myint1_e {min1 = -32767, max1 = 32767};
 enum myint2_e {min2 = -32767, max2 = 32767};
 typedef enum myint1_e integer1_t;
 typedef enum myint2_e integer2_t;

 integer1_t x1 = 0;
 integer2_t x2 = 0;
Run Code Online (Sandbox Code Playgroud)

现在,这两种类型enum myint1_tenum myint2_t是不同的整数类型。
参见 C11:6.7.2.3(第 5 段):

位于不同作用域或使用不同标记的两个枚举类型声明声明不同的类型。

因此,他们的typedef-ed 版本也不同。
因此,变量x1x2具有不同的类型。
整数值 0 可以分配给这两个变量。

现在,如果您想检查变量的类型是否是您想要的类型,您可以尝试这样做:

 #define VERIFY_INT1TYPE(a) ((integer1_t*)(0) == (&a))
Run Code Online (Sandbox Code Playgroud)

但此方法仅提供警告消息,而不是您期望的“与值比较 false”。

说明:虽然整数类型在某种程度上可以在赋值操作中互换,但另一方面它们的“指针”版本始终是不同的类型。因此,像这样的句子x1 == x2根本没有任何问题,但是比较两个不同指针类型的值会引发警告消息

备注: 表达式(integer1_t*)(0)是将 NULL 指针转换为类型integer1_t*

例子:

  VERIFY_INT1TYPE(x2);  
Run Code Online (Sandbox Code Playgroud)

当我使用 GCC 编译时,此示例会发出警告消息。