Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C宏中验证类型_C_C Preprocessor - Fatal编程技术网

如何在C宏中验证类型

如何在C宏中验证类型,c,c-preprocessor,C,C Preprocessor,我一直在考虑在C宏中验证类型的方法,到目前为止,我想到的最好的方法是: #define ASSERT_PTYPE(TYPE, VALUE) (0 && (*(int (*)(TYPE*))0)(VALUE)) 这显然需要一个类型名和指向该类型的指针。也可以创建类似的ASSERT_类型宏。这似乎与GCC配合得很好。在类型不匹配的情况下,它甚至会给出非常有用的错误消息。问题是,我不能完全肯定这是有效的C或者是最好的方法 据我所知,标准规定可以强制转换函数指针,但调用强制转换函数指针

我一直在考虑在C宏中验证类型的方法,到目前为止,我想到的最好的方法是:

#define ASSERT_PTYPE(TYPE, VALUE) (0 && (*(int (*)(TYPE*))0)(VALUE))
这显然需要一个类型名和指向该类型的指针。也可以创建类似的ASSERT_类型宏。这似乎与GCC配合得很好。在类型不匹配的情况下,它甚至会给出非常有用的错误消息。问题是,我不能完全肯定这是有效的C或者是最好的方法


据我所知,标准规定可以强制转换函数指针,但调用强制转换函数指针的结果未定义。在这种情况下,不可能在运行时调用函数。这是否足够好,或者标准是否意味着您甚至无法编写无法调用强制转换函数的代码?

使用C99和复合文本,您可以执行以下操作

#define ASSERT_TYPE(TYPE, VALUE) ((TYPE){ 0 } = (VALUE))
这可确保
的赋值与
类型
兼容。由于赋值,表达式返回一个右值

复合文本在函数范围和文件范围内工作,任何合适的编译器都应该优化额外创建的对象

添加
该宏中的类型
可以是除数组之外的任何有效类型名称,例如指针
双*
、结构或联合
结构toto
。由于赋值的原因,
double[4]
等数组类型将不起作用。使用指针指向 数组
double(*)[4]
,例如

double A[4];
(*ASSERT_TYPE(double(*)[4], &A))

第二行是一个值为“<代码>双[ 4 ] < /代码>的编译值,该属性是编译时间。

好问题,这里有一个可能的C++对应的问题是…在C语言中,程序员还不知道传递给该宏的类型的情况有哪些?代码的用途是什么?此外,这些都不能解决与C语言中的许多隐式类型转换相关的任何问题。例如,就C而言,有符号和无符号是兼容的。它不应该读
(TYPE*){0}
,因为他想断言
VALUE
具有指向
TYPE
的类型指针(宏的名称是
assert\PTYPE
而不是
assert\TYPE
)@Curd,不,建议的解决方案适用于任何类型,不仅仅是指针类型。我将其重命名为
ASSERT\u TYPE
,以使其更清晰。要将它用于指针类型,您只需将这样的指针类型作为第一个参数,例如类似于
double*
之类的东西。这正是我想要得到的。这里唯一的负面影响是错误消息比从伪函数调用中得到的消息要少一些。此外,在使用示例中,我认为您的意思是宏返回的是右值而不是左值,对吗?@ltc,不,我是指左值
ASSERT_TYPE
返回一个右值,但它是指向数组的指针。取消对它的引用将为您提供原始数组
A
。例如,你可以再次引用它,如果它是右值,你就不能引用它。