c/c++语言开发共享Variadic异质FREE宏

我想要一个宏来释放不同类型的多个(可变数字)指针。 基于SO中的类似问题,我制作了这个代码似乎有效

#include  #include  #include  /* 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); } 

我的问题是

    一个潜在的可用性问题是它不能扩展到只释放一个指针,类似于常规的free 。 虽然这不是必需的(因为您可能要求用户发现并free使用),但通常优雅的是尽可能通用并自动扩展以适应此类用例。

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

    如果宏定义中的标识符列表没有以省略号结尾…否则,调用中的参数应该多于宏定义中的参数(不包括... )。

    即在严格符合C的情况下,必须使用__VA_ARGS__ 。 当使用-std=c99 -Wall -pedantic时,GCC甚至会为你强调这一点(编译器无法certificate某些东西合规的,但它可以警告你什么时候没有):

    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,); – 一个空的宏参数仍然是一个参数,它填充的数组初始化程序也允许尾随逗号),但这不是很…与语言融为一体。

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

    这很酷,是的,使用void *是正确的。

    你可以稍微改进它(更常见,当然使用size_t而不是unsigned )但总的来说它似乎没问题。

    另外,在main()删除强制转换, 不需要在C中强制转换malloc()的返回值,这样做可以掩盖实际错误,所以它很糟糕。

    为了解决@ Leushenko的答案 ,您可以通过添加额外的宏扩展步骤来粘合一些东西,该步骤总是在varargs宏调用中添加NULL。 这样,即使只用一个参数调用顶层宏,你也永远不会用一个参数调用实际的varargs宏。 当然,调用free(NULL)总是安全且定义良好的,所以应该可行。

      以上就是c/c++开发分享Variadic异质FREE宏相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

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

      ctvol管理联系方式QQ:251552304

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

      (0)
      上一篇 2021年1月14日
      下一篇 2021年1月14日

      精彩推荐