免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 6961 | 回复: 21
打印 上一主题 下一主题

[C] 如何在C89规范下实现可变参数的宏? [复制链接]

论坛徽章:
0
跳转到指定楼层
[收藏(0)] [报告]
发表于 2008-07-14 14:57 |只看该作者 |正序浏览
5可用积分
我写了一个函数,用于控制在不同的日志级别下输出日志信息。函数原型如下:
void errlog( int loglevel, const char *errfile, const char *arglist, ... );
为方便使用,想通过宏定义重新命名几个函数,例如errlog0、errlog1、errlog2。
在C99规范下实现很简单,可以以下面的形式声明:
#define errlog0( errfile, ... )   errlog( LOGLEVEL_0, errfile, __VA_ARGS__ )
#define errlog1( errfile, ... )   errlog( LOGLEVEL_1, errfile, __VA_ARGS__ )
#define errlog2( errfile, ... )   errlog( LOGLEVEL_2, errfile, __VA_ARGS__ )
但在C89规范下(例如SCO所带的cc),这种定义形式是不被接受的。
有谁有好的解决办法?

论坛徽章:
0
21 [报告]
发表于 2008-12-30 16:05 |只看该作者

回复 #19 smallstar001 的帖子

好像必须要加这对括号,要不然,会被解析为多个参数
然后编译就不会通过

论坛徽章:
0
20 [报告]
发表于 2008-12-30 14:26 |只看该作者
ACE当中采用的是最后一种方法,所以要可移植性的话还是采用最后一种比较好
#define ACE_DEBUG(X) \
  do { \
    int __ace_error = ACE_Log_Msg::last_error_adapter (); \
    ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \
    ace___->conditional_set (__FILE__, __LINE__, 0, __ace_error); \
    ace___->log X; \
  } while (0)

论坛徽章:
0
19 [报告]
发表于 2008-12-30 14:23 |只看该作者
#define debug(fmt,...) printf(fmt,__VA_ARGS__ )
#define debug(fmt,args...) printf(fmt,##args)
#define debug(X) printf X


用过这3种。。。

论坛徽章:
0
18 [报告]
发表于 2008-12-29 13:21 |只看该作者
原帖由 sunlan 于 2008-7-14 21:46 发表

也不完全是这样。看一下下面这个例子:

#include
#include

#define DEBUG(args)  (printf args)

int main()
{
    int n=5;

    DEBUG( ("n is %d  c is %c\n", n, 'C')  );    //注意这里“ ...



想问的是那多一对括号有什么好处??

论坛徽章:
0
17 [报告]
发表于 2008-12-29 11:21 |只看该作者
Up

论坛徽章:
0
16 [报告]
发表于 2008-07-15 20:37 |只看该作者
那我也跟你变通一下:
#define DEBUG(fmt,...) DEBUG1((fmt,__VA_ARGS__))
#define DEBUG1( args ) printf args
不知道行不行哈,没试过,我也没有C89的环境,楼主自己试一下

论坛徽章:
0
15 [报告]
发表于 2008-07-15 13:42 |只看该作者
原帖由 jamesr 于 2008-7-15 10:06 发表
还是C99好啊!各个系统的API都已经采用C99了。

问题是有些老系统不支持,比如说sco。但又必须考虑对这些系统的兼容性

论坛徽章:
0
14 [报告]
发表于 2008-07-15 10:06 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
13 [报告]
发表于 2008-07-15 09:19 |只看该作者
而c我一般做法是直接指定以后要传入多少个参数,如:

MACRO_1(fmt, arg1)
MACRO_2(fmt, arg1, arg2)
...

论坛徽章:
0
12 [报告]
发表于 2008-07-15 09:15 |只看该作者
算法思路:
1〉#define 后面跟类名,构造时传入__FILE__等宏信息
2〉重载括号操作符(operator()),注意指定好你要的函数调用协议(一般是cdecl)
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP