Chinaunix首页 | 论坛 | 博客
  • 博客访问: 339530
  • 博文数量: 88
  • 博客积分: 1695
  • 博客等级: 上尉
  • 技术积分: 1380
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-06 15:48
个人简介

喜欢美食, 旅行..

文章分类

全部博文(88)

文章存档

2014年(2)

2013年(12)

2012年(14)

2010年(8)

2009年(52)

我的朋友

分类: C/C++

2012-11-01 12:09:41

原理很简单,就是要骗过编译器,让编译器觉得不是冲突的那个宏名字符号.
== 以下的例子假设都已经定义了宏 test ,这个宏名字的污染已经导致我们定义不了 test符号了.
== 即已经有了 #define test "MarcoTestExist" 的宏定义语句存在.

1. 符号定义时的冲突解决方案

1.1. 名字包装. <我经常使用的一种方法>
int (test)() { return 10; } // 用圆括号包装test, 编译器看到 "(test)" 和 "test" 是不一样的符号.

当然你可以使用其他的包装方式, 比如干脆就加个前缀, 比如 int my_test(){...}.
我建议还是使用圆括号来包装, 这样来包装的话, 你还是可以正常的使用 test 这个符号.

1.2. 使用宏的技术 < 这一招是从boost里面学到的, 这里还是以boost里面的符号名称为例. >
#define BOOST_PREVENT_MACRO_SUBSTITUTION
int test BOOST_PREVENT_MACRO_SUBSTITUTION() { return 10; }

我这里只是简单的定义 BOOST_PREVENT_MACRO_SUBSTITUTION 为空, 这样已经足以骗过编译器了.boost里面的实现就不那么单纯, 如果读者有兴趣, 可以自行去研究.

2. 使用符号时冲突的解决方案
1.1. 名字包装. <我经常使用的一种方法,原理同上.>
cout << (test)() << endl;

1.2. 使用宏的技术 < 原理同上. >
#define BOOST_PREVENT_MACRO_SUBSTITUTION
cout << test BOOST_PREVENT_MACRO_SUBSTITUTION() << endl;

3. 一个完整的测试样例 < vc2005验证通过 >
#define test(A,B) ( "call macro test" )
#define BOOST_PREVENT_MACRO_SUBSTITUTION
// #include

char* (test)(int a, int b)
{    return "call function test"; }
namespace ns
{
    char* test BOOST_PREVENT_MACRO_SUBSTITUTION(int a,int b)
    {    return "call function ns::test"; }
}
int main ( int, char ** )
{
    cout <<      test (1,2) << endl; // call macro test
    cout <<     (test)(1,2) << endl; // call function test
    cout << (ns::test)(1,2) << endl; // call function ns::test

    cout <<     test BOOST_PREVENT_MACRO_SUBSTITUTION(1,2) << endl; // call function test
    cout << ns::test BOOST_PREVENT_MACRO_SUBSTITUTION(1,2) << endl; // call function ns::test

    return 0;
}


阅读(2813) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~