c/c++语言开发共享使用宏进行类型generics编程:确定类型的技巧?

可以将某些类型的类型generics函数作为C中的宏来执行,例如:

#define SQRT(x) (sizeof(x) == sizeof(float) ? sqrtf((x)) :  sizeof(x) == sizeof(double) ? sqrt((x)) :  sqrtl((x)) ) 

只要x是浮点类型,这(大多数情况下)就可以正常工作。

但是,如果我想要一个可以采用整数类型或指针类型的类型通用宏,它可能具有相同的大小。 有没有一种聪明的方法来测试宏参数是整数还是指针? 整数与浮点类型怎么样?

    不,Macros不知道是什么类型。 它们执行#define的文字复制和粘贴。 这里根本不存在类型安全。

    C在任何有意义的意义上都不是强类型语言。 如果你想要一些类型安全的modicum,使用C ++,你可以用模板和函数重载完成一些。

    你的结果并不是真正的类型generics,因为无论传递什么类型的参数,结果都总是long double – 结果类型为?:当第二个和第三个操作数是算术类型时,应用的结果类型是通常对这些操作数的算术转换。 为此,您可以使用GCC的扩展类型:

     #define SQRT(x) (__typeof__ (x))(sizeof(x) == sizeof(float) ? sqrtf((x)) :  sizeof(x) == sizeof(double) ? sqrt((x)) :  sqrtl((x)) ) 

    整数与浮点也可以使用typeof来完成:

     (__typeof__ (X))1.1 == 1 

    我想不出一种做整数对指针的方法。 不过, 本页描述的技术非常有趣。

    您可以检测表达式是整数表达式还是char*表达式,至少在从指针uintptr_t定义的uintptr_t是这样:

     #define INT_OR_CHARP(X) (((uintptr_t)((X)+1) - (uintptr_t)(X)) == 1) 

    这将检测X是否是指向sizeof(T) > 1的类型T的指针。 这不适用于void*和其他极端情况。 因为X被评估了两次,你必须注意副作用。

    为了避免整数溢出问题,如果X是例如signed int类型,你可以替换(X)

     (1 ? (X) : (uintmax_t)0) 

    这保证了如果X是整数表达式,则它将是uintmax_t类型。 然后+1可能会回绕,但结果总是很明确,两个部分之间的差异总是1 。 如果X是指针表达式,那么这是因为任何值0常量整数表达式也是空指针常量

    总的来说这给了

     #define INT_OR_CHARP(X) (((uintptr_t)((1 ? (X) : (uintmax_t)0)+1) - (uintptr_t)(1 ? (X) : (uintmax_t)0)) == 1) 

    为此,在C11标准中添加了_Generic关键字。

    它的工作方式类似于表达式类型的switch语句。

    您的示例可以使用此关键字编写,如下所示:

     #define SQRT(X) _Generic((X), float: sqrtf,  double: sqrt,  default: sqrtl  )(X) 

    自4.9版以来,GCC为此关键字提供支持。

    有可能有某种类型检查系统,但它确实是C中的kludge。

    glib做到了这一点; 你可以看看他们是如何做到的,或者可能是自己使用它(无论如何,它都是一个漂亮的C库)。

    需要了解更多c/c++开发分享使用宏进行类型generics编程:确定类型的技巧?,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!

      以上就是c/c++开发分享使用宏进行类型generics编程:确定类型的技巧?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/978989.html

      (0)
      上一篇 2021年12月12日
      下一篇 2021年12月12日

      精彩推荐