在编译时,在c / c ++预处理宏中验证参数是ARRAY类型 [英] Validate an argument is ARRAY type in c/c++ pre processing macro on compile time

查看:118
本文介绍了在编译时,在c / c ++预处理宏中验证参数是ARRAY类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



例如在这两个宏中:

$ b $在ac宏中编译时验证一个参数是一个数组吗? b

  #define CLEAN_ARRAY(arr)\ 
do {\
bzero(arr,sizeof(arr)); \
} while(0)



  #define ARRAY_SIZE(x)(sizeof(x)/ sizeof((x)[0]))
pre>

我尝试了一些使用 CTC(X) ,但是如果 arr 不是数组,则找不到验证/警告的任何方法。

解决方案

以下是纯C中的一个解决方案,它不会调用未定义的行为:

 (arg)(sizeof(arg [0]))
#define IS_ARRAY(arg)(IS_INDEXABLE(arg)&&((void *)& arg) ==((void *)arg)))

如果您需要确保该值为数组(如果不是,则会导致编译时错误),您可以简单地将它用作enum语句(或静态变量)的初始化程序,如下所示:

  static int __ ## arg ## _is_array = IS_ARRAY(arg); //为数组工作,失败的指针。 

我不完全确定VLA会发生什么,但是玩一下应该会找到答案




老答案:

因为这个被标记为C(和GCC),我会在这里尝试一个解决方案:

  #define IS_ARRAY(arg)__builtin_choose_expr(__ builtin_types_compatible_p(typeof (arg [0])[],typeof(arg)),1,0)

,使用C11的 _Generic 功能& typeof

  #define IS_ARRAY(arg)_Generic((arg) ,\ 
typeof(arg [0])*:0,\
typeof(arg [0])[sizeof(arg)/ sizeof(arg [0])]:1 \





$ b基本上,它所做的只是使用GCC的一些奇特功能来确定类型的参数与参数元素类型的数组兼容。它会返回0或1,如果你愿意的话,你可以将0替换为会产生编译时错误的东西。


Is there any way to validate on compile time in a c macro that an argument is an array ?

e.g in this two macros:

#define CLEAN_ARRAY(arr) \
    do { \
        bzero(arr, sizeof(arr)); \
    } while (0)

And

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

I tried something using CTC(X) macro , but couldn't find any way to validate/warn if arr isn't an array.

解决方案

Here's a solution in pure C which invokes no undefined behavior:

#define IS_INDEXABLE(arg) (sizeof(arg[0]))
#define IS_ARRAY(arg) (IS_INDEXABLE(arg) && (((void *) &arg) == ((void *) arg)))

If you need to ensure that the value is an array (then cause a compile time error if not), you can simply use it as an initializer to an enum statement (or a static variable), like this:

static int __ ## arg ## _is_array = IS_ARRAY(arg); // works for an array, fails for pointer.

I'm not entirely sure what will happen with VLA's, but playing around a bit should find that answer out rather fast.


Old answers:

Since this is tagged C (and GCC), I will attempt a solution here:

#define IS_ARRAY(arg) __builtin_choose_expr(__builtin_types_compatible_p(typeof(arg[0]) [], typeof(arg)), 1, 0)

Another solution, using C11's _Generic feature & typeof:

#define IS_ARRAY(arg) _Generic((arg),\
    typeof(arg[0]) *: 0,\
    typeof(arg[0]) [sizeof(arg) / sizeof(arg[0])]: 1\
)

Basically, all it does is use some fancy features of GCC to determine if the type of the argument is compatible with an array of the type of the argument's elements. It will return 0 or 1, and you could replace the 0 with something that creates a compile time error if you wish.

这篇关于在编译时,在c / c ++预处理宏中验证参数是ARRAY类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆