高分求解(关于宏定义)

Macor 2007-07-05 06:25:53
#include <iostream>
#include <stdio.h>

#define FUNC2(x, y) x##y
#define FUNC1(x, y) FUNC2(x, y)

#if 1 // 1如果换为0就出错,为什么?
#define FUNC(z) FUNC1(z, __LINE__)
#else
#define FUNC(z) FUNC2(z, __LINE__)
#endif

int FUNC(my_unique_prefix_);
int FUNC(my_unique_prefix_);

int main()
{
}
...全文
247 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
blue_zyb 2007-07-06
  • 打赏
  • 举报
回复
不错不错,学习了
Macor 2007-07-06
  • 打赏
  • 举报
回复
to healer_kx :

刚刚搞明白,CL /E **.cpp的用法,分数已经给了,下次再给你:)
Macor 2007-07-06
  • 打赏
  • 举报
回复
搞定,SDK上有清晰描述:),谢谢大家,过会结帖
healer_kx 2007-07-06
  • 打赏
  • 举报
回复
CL /E **.cpp
Macor 2007-07-06
  • 打赏
  • 举报
回复
to deng2000:

解释得真清楚,谢谢:)

另外问个问题:
用VC的 cl /EP命令可以得到预编译的处理结果, 这里的 cl /EP命令怎么用?

deng2000 2007-07-06
  • 打赏
  • 举报
回复
用VC的 cl /EP命令可以得到预编译的处理结果.程序中的如下两行:

int FUNC(my_unique_prefix_);
int FUNC(my_unique_prefix_);

在"#if 1"的情况下,被换成:

int my_unique_prefix_10;
int my_unique_prefix_11;

而在"#if 0"的情况下,这两行变为:

int my_unique_prefix___LINE__;
int my_unique_prefix___LINE__;

同一个变量被声明两次,因此出编译错.
可以看出,问题的关键在于,前一种情况__LINE__被置换成当前行号(10和11)后参与##运算,而后一种情况中,_LINE_并没有被替换,而是直接作为字串参与##运算.
这个结果有点出人意料. 象xlfddlfd说的,FUNC1和FUNC2应该等价呀,为什么会这样?

回答这个问题需要了解预编译处理函数宏(例如FUNC1,FUNC2)的一个原则: 一般情况下,先把参数中的宏展开,再替换函数本身.但有几种例外情况是不预先处理参数而直接处理函数的,其中一种情况就是:参数中的宏要参与"##"连接运算.详细情况见http://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html#Argument-Prescan
这里只举一个例子说明:
如有
#define AFTERX(x) X_ ## x
#define XAFTERX(x) AFTERX(x)
#define TABLESIZE 1024
#define BUFSIZE TABLESIZE

则AFTERX(BUFSIZE) 展开成为 X_BUFSIZE, 而 XAFTERX(BUFSIZE) 展开成为 X_1024.

回到本题,在"#if 1"的情况下, #define FUNC(z) FUNC1(z, __LINE__), 因此
int FUNC(my_unique_prefix_);
首先被换成:
int FUNC1(my_unique_prefix_, __LINE__);
接下来,是先处理FUNC1还是__LINE__? 预编译程序先看看FUNC1的定义: #define FUNC1(x, y) FUNC2(x, y) , 其中并没有x和y的合并运算(这时它不会去管FUNC2内部如何处理),因此按上面的原则,首先展开参数宏,变为:

int FUNC1(my_unique_prefix_, 10); (假设当前行是10)
再展开函数宏FUNC1本身,变成:
int FUNC2(my_unique_prefix_, 10);
FUNC2又是一个函数宏,前面的过程再来一遍.不过此时两个参数都不是宏了,因此只需依定义替换FUNC2:
int my_unique_prefix_10
这就是最后的替换结果.同理,处理下一行的int FUNC(my_unique_prefix_);时,结果为
int my_unique_prefix_11
因为当前行数增加了1

而在"#if 0"的情况下, #define FUNC(z) FUNC2(z, __LINE__), 因此
int FUNC(my_unique_prefix_);
首先被换成:
int FUNC2(my_unique_prefix_, __LINE__);
预编译器查看FUNC2的定义: #define FUNC2(x, y) x##y ,参数要进行##合并运算,因此按上面的原则,不用处理参数而直接处理函数FUNC2,变为:

int my_unique_prefix___LINE__;

展开的结果不再包含宏,处理完毕.注意__LINE__成了变量名的一部分,再也得不到机会展开成当前行号了. 而处理下一行的int FUNC(my_unique_prefix_);时,结果是一模一样的,因为不涉及到当前行号.
jinwei1984 2007-07-05
  • 打赏
  • 举报
回复
mark
xlfddlfd 2007-07-05
  • 打赏
  • 举报
回复
刚回复3次不让回了。。。
真晕。。。
xlfddlfd 2007-07-05
  • 打赏
  • 举报
回复
刚试验了下把#define FUNC1(x,y) FUNC2(x,y)换成#define FUNC1(x,y) x##y不管是0或者1都是重复定义。
实践证明
#define FUNC1(x,y) FUNC2(x,y) 和
#define FUNC1(x,y) x##y
不等价。。。why?
  • 打赏
  • 举报
回复
展开以后是
int my_unique_prefix___LINE__;
int my_unique_prefix___LINE__;
xlfddlfd 2007-07-05
  • 打赏
  • 举报
回复
#define FUNC2(x, y) x##y
#define FUNC1(x, y) FUNC2(x, y)
-----------------------------------------
在VC6试了下,重复定义。。。
FUNC1和FUNC2应该等价啊?怎么会出现重复定义?
xlfddlfd 2007-07-05
  • 打赏
  • 举报
回复
晕,看走眼了:(
xlfddlfd 2007-07-05
  • 打赏
  • 举报
回复
int FUNC(my_unique_prefix_);
int FUNC(my_unique_prefix_);
----------------------------------------
以上重复定义撒,删去一行^_^
iu_81 2007-07-05
  • 打赏
  • 举报
回复
#if 0
// 输出一些调试信息或调试处理
#endif

当程序出错时 把#if 0变成#if 1. 这样 #if #endif之间的代码便可以成为代码
的一部分,从而输出有用的调试信息

当程序无误时用#if 0时使预处理器忽略此段代码.

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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