Codejie's C++ Space

Using C++

求解:变参宏定义


    看《xxx的自我修养》里面有一段关于“变长参数宏”的代码:
#include <stdio.h>

#define printf(args ) fprintf(stdout, ##args)

int main()
{
        printf(
"\n%d, %s\n"0"test");

        
return 0;

}
    代码不长,编译也未见问题,结果也正常,演示了其想说明的部分。根据其意,‘##’宏用于字符串的连接操作,即将参数‘args’部分连接成一个字符串传给fprintf函数。但我认为宏定义本身就是‘字符串的替换’,完全不需要‘##’,即,传人的‘args’是什么,fprintf被传人的也是什么,不会有任何变化,也无需作任何操作,因此我修改宏如下:

#define printf(args ) fprintf(stdout, args)
    嗯,我获得了相同的正常结果。

   从结果看,我认为《自我修养》想通过这个例子说明‘##’的使用方式,是不太恰当的。下面是我使用的GCC的版本信息:
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/3.3.2/specs
Configured with: ..
/configure --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld --disable-nls
Thread model: posix
gcc version 
3.3.2


    现在问题是这个‘...’了。
    如果说,宏定义本身就是‘字符串的替换’,那么,这里‘...’应该没有任何用处。于是,修改宏如下:
#define printf(args) fprintf(stdout, args)
    结果编译得到如下错误:
print.cpp:7:38: macro "printf" passed 3 arguments, but takes just 1

    为什么会这样?没找到原因,无论对args加上‘##’,还是‘()’,都是一样的错误结果。
    实话说,我从未写过类似'args ...'这样的参数,按我的理解,这语法检查的实话就应该出差了,但事实却没有。
     各位对'...'的用法有啥见解?


<----自作聪明的分割线---->
    g++的 -C -E参数对付宏和模版的调试很好用。。。

posted on 2009-08-24 15:05 codejie 阅读(1804) 评论(4)  编辑 收藏 引用 所属分类: C++

评论

# re: 求解:变参宏定义[未登录] 2010-10-14 14:48 K

args...是变参的意思,因为printf(format, ...)后面那个参数是变长的,你这边的写法 #define printf(args...) fprintf(stdout, args),左边第一个args...代表变参,右边args就直接指代该变参,我也不明白书里为什么有##  回复  更多评论   

# re: 求解:变参宏定义[未登录] 2011-01-26 00:04 louis

这是为了在参数为空时消除逗号 @K
  回复  更多评论   

# re: 求解:变参宏定义 2011-09-21 13:42 余楚伟

你修改之后的宏除了format之外,至少需要一个参数;而《XXX的自我修养》则不需要。  回复  更多评论   

# re: 求解:变参宏定义 2011-09-23 10:28 codejie

@余楚伟
这样啊。。回头试试,谢谢。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

Using C++

导航

统计

留言簿(73)

随笔分类(513)

积分与排名

最新评论

阅读排行榜

评论排行榜