可变参数异构FREE宏 [英] Variadic heterogenous FREE macro

查看:100
本文介绍了可变参数异构FREE宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望宏释放不同类型的多个(变数)指针.基于SO中的类似问题,我编写了似乎可行的代码

I want a macro to free multiple (variadic number) pointers of different type. Based on similar questions in SO I made this code which seems to work

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

/* your compiler may need to define i outside the loop */
#define FREE(ptr1, ...) do{\
    void *elems[] = {ptr1, __VA_ARGS__};\
    unsigned num = sizeof(elems) / sizeof(elems[0]);\
    for (unsigned i=0; i < num; ++i) free(elems[i]);\
} while(0)


int main(void) 
{
    double *x = malloc(sizeof(double)); /* your compiler may need a cast */
    int    *y = malloc(   sizeof(int)); /* ditto */

    FREE(x, y); 
}

我的问题是

  • 在这种情况下创建void*数组是否正确? (我在*int[]上看到了相同的技巧,所以问题是*void[]会做我期望的事情)
  • 代码是否符合C99,是否有任何编译器对此有问题?
  • Is the creation of a void* array correct in this context? (I saw the same trick with *int[], so the question is will a *void[] do what I expect)
  • Is the code C99 compliant, are there any compilers that would have problems with this?

推荐答案

一个潜在的可用性问题是,它不能像常规的free那样仅扩展到释放单个指针.尽管这不是必需的(因为您可能要求用户发现它并使用free),但对于尽可能通用的事物并自动调整自身以适应此类用例,通常是很优雅的.

One potential usability problem with this is that it doesn't scale to freeing only a single pointer, similar to the regular free. While this isn't necessary (since you could require the user to spot this and use free), it's usually elegant for things to be as generic as possible and automatically scale themselves to fit such use cases.

C99 (也 C11 )标准部分6.10.3第4段:

C99 (also C11) standard section 6.10.3 paragraph 4:

如果宏定义中的标识符列表不以省略号结尾...否则,与宏定义中的参数相比,调用中的应有更多的参数(不包括...).

即在严格符合C的情况下,必须使用__VA_ARGS__.当使用-std=c99 -Wall -pedantic时,GCC甚至会为您突出显示此内容(编译器无法证明 兼容,但是当不符合时它会警告您):

i.e. in strictly conforming C, the __VA_ARGS__ must be used. GCC will even highlight this for you (a compiler can't prove something is compliant, but it can warn you when it isn't) when using -std=c99 -Wall -pedantic:

test.c: In function 'main':
test.c:18:11: warning: ISO C99 requires rest arguments to be used [enabled by default] FREE(x); ^

test.c: In function 'main':
test.c:18:11: warning: ISO C99 requires rest arguments to be used [enabled by default] FREE(x); ^

从技术上讲,您不需要实际值,只需要末尾逗号(FREE(x,);-空的宏参数仍然是参数,并且其所填充的数组初始化程序还允许末尾逗号),但这不是非常实际的...与语言融为一体.

Technically you don't need the actual value, just the trailing comma (FREE(x,); - an empty macro argument is still an argument, and the array initializer it populates also allows trailing commas), but that's not very... integrated with the language.

在实践中,实际的编译器不会直接反对缺少rest-args,但是它们可能会发出警告(如上所示),因为非致命错误通常可以合理地解释为其他地方出了问题的迹象.

In practice real compilers won't directly object to missing rest-args, but they might warn about it (as shown above), because a non-fatal error is often reasonable to interpret as a sign that something is wrong elsewhere.

这篇关于可变参数异构FREE宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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