aix53中宏中使用可变参数的问题

dengyiyu 2010-09-19 10:25:23
我在job_exception.h中定义了如下函数:
__cdecl JobSchedulerException(JobSchedulerExceptionType exception_type,
int error_code, const char* throw_filename,int throw_line,const char* msg_format
, ...);

同时定义了如下宏:
#define ThrowException(enum_exception_type,error_code,err_msg,...) {\
throw ECIFPB::JobSchedulerException(enum_exception_type,(int)err
or_code,__FILE__,__LINE__,err_msg,##__VA_ARGS__);}


在其它.cc文件中使用ThrowException(my_type,errno,"错误信息");时报错误:
Too few arguments are specified for macro "ThrowException". Empty arguments are used.

为什么呢?
...全文
100 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
快乐田伯光 2010-09-19
  • 打赏
  • 举报
回复
这个跟gcc的版本有关, 通常做法如下:

#if defined(__GNUC__) && (__GNUC__ < 3)
#define LOG_ERROR(args...) \
fprintf( stdout , "Error: %u:%s\n", __LINE__, __FILE__); \
fprintf( stdout , ## args ); \
fprintf( stdout , "\n" );
#else
#define LOG_ERROR(...) \
fprintf( stdout , "Error: %u:%s\n", __LINE__, __FILE__); \
fprintf( stdout , __VA_ARGS__); \
fprintf( stdout , "\n" );
#endif

mymtom 2010-09-19
  • 打赏
  • 举报
回复
或者修改程序
ThrowException(my_type,errno,"错误信息");
===>
ThrowException(my_type,errno, "%s", "错误信息");

这样比较安全,也可以移植到其他系统上。
就我所知道的,HP-UX上的aCC对变参宏的支持就不全面。

这是从IBM的网站上的
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/topic/com.ibm.xlcpp8a.doc/compiler/ref/ruoptlvl.htm#ruoptlvl

[no]gnu_varargmacros This option is similar to -qlanglvl=varargmacros. The main differences are:

* An optional variable argument identifier may precede the ellipsis, allowing that identifier to be used in place of the macro __VA_ARGS__ . Whitespace may appear between the identifier and the ellipsis.
* The variable argument can be omitted.
* If the token paste operator (##) appears between the comma and the variable argument, the preprocessor removes the dangling comma (,) if the variable argument is not provided.
* The macro __IBM_MACRO_WITH_VA_ARGS is defined to 1.

Example 1 - Simple substitution:

#define debug(format, args...) printf(format, args)

debug("Hello %s\n", "Chris");

preprocesses to:

printf("Hello %s\n", "Chris");

Example 2 - Omitting the variable argument:

#define debug(format, args...) printf(format, args)

debug("Hello\n");

preprocesses to the following, leaving a dangling comma:

printf("Hello\n",);

Example 3 - Using the token paste operator to remove a dangling comma when the variable argument is omitted:

#define debug(format, args...) printf(format, ## args)

debug("Hello\n");

preprocesses to:

printf("Hello\n");
mymtom 2010-09-19
  • 打赏
  • 举报
回复
试试加xlc++的编译选项:
-qlanglvl=gnu_varargmacros
justkk 2010-09-19
  • 打赏
  • 举报
回复
#include <stdio.h>
#define log_(...) \
do {\
printf(__VA_ARGS__);\
} while(0)

main()
{
log_("%d, %d\n", 1, 2);
log_("%s", "hello\n");
}

参考..
dengyiyu 2010-09-19
  • 打赏
  • 举报
回复
在开发机上使用#define ThrowException(enum_exception_type,error_code,err_msg,arg...) {\
throw ECIFPB::JobSchedulerException(enum_exception_type,(int)err
or_code,__FILE__,__LINE__,err_msg,##args);}
编译和运行都没问题。

然后拿到另外一台机器上报...处错误,于是改成了上面的那个宏,这时候编译没问题,运行时又出问题了。
dengyiyu 2010-09-19
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 justkk 的回复:]
你的__VA_ARGS__前不需要使用##
[/Quote]

去掉##错误也是一样的
justkk 2010-09-19
  • 打赏
  • 举报
回复
你的__VA_ARGS__前不需要使用##
dengyiyu 2010-09-19
  • 打赏
  • 举报
回复
job_exception.h和job_exception.cc编译是通过的了,就是在其它cc文件中调用宏的时候报错。
dengyiyu 2010-09-19
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 mymtom 的回复:]
或者修改程序
ThrowException(my_type,errno,"错误信息");
===>
ThrowException(my_type,errno, "%s", "错误信息");

这样比较安全,也可以移植到其他系统上。
就我所知道的,HP-UX上的aCC对变参宏的支持就不全面。

这是从IBM的网站上的
http://publib.boulder.ibm.com/in……
[/Quote]

这样改是没有问题的,只是代码里有太多的地方都只能三个参数的了。
加编译选项:
-qlanglvl=gnu_varargmacros试了,好像还是不行的。

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧