1 #include  < iostream >
 2 using   namespace  std;
 3
 4 #define  MAX 1<<4
 5 #define  MAX_ADJUST (1<<4)
 6 #define  repeated(b,m) (b & m & (b & m)-1)
 7 #define  repeated_(b,m) ((b) & (m) & ((b) & (m))-1)
 8
 9 typedef unsigned  short  Bits;
10
11 enum   { bit01 = 1<<0
12    bit02 = 1<<1
13    bit03 = 1<<2,
14    bit04 = 1<<3,
15    bit05 = 1<<4,
16    bit06 = 1<<5,
17}
;
18
19 int  main()
20 {
21
22    cout << "MAX = "<< MAX << endl;//oops!
23    cout << "MAX*2 = "<< MAX*2 << endl;//oops!
24
25    int a = MAX;
26    int b = MAX*2;
27
28    cout << "MAX = "<< a << endl;//oops!
29    cout << "MAX*2 = "<< b << endl;//oops!
30
31    cout << "MAX_ADJUST = "<< MAX_ADJUST << endl;
32    cout << "MAX_ADJUST*2 = "<< MAX_ADJUST*2 << endl;
33
34    Bits aa = 0;
35    Bits bb = 0;
36    const Bits mask = bit02 | bit03 | bit06; //mask = 100110
37    cout << repeated(bb+bit02,mask) << endl;//oops!
38    cout << repeated_(bb+bit02,mask) << endl;
39    cout << repeated(aa+=bit02,mask) << endl;//oops!
40    cout << repeated_(aa+=bit02,mask) << endl;
41
42    return 0;
43}

44

 

使用预处理器符号的基本问题在于,预处理器在C++编译器检查这些符号之前,就展开了这些符号。预处理器对C++的作用域或者类型规则一无所知。
#define字面值
如果声明一个数组,int b[MAX*2]
MAX = 16
MAX*2 = 256
可以看到如果本意只是声明一个大小16*2=32的数组,则声明的数组实际大小会比预想的大得多

#define定义伪函数(pseudofunction)
37,38行在这里虽然输出结果时一样的,主要是因为+优先级高于位与&,相当于隐形加了括号,但可以想象,当特定时候,优先级并不能保证有个隐形的括号时,会出现错误。
没有在伪函数中加入足够的括号,这是常见的错误。
然而,碰到39,40行的情况时,错误还是会出现,
传递给伪函数的第一个参数有副作用,如果repeated是真正的函数,则副作用仅仅会在调用函数之前出现一次。在这个repeated的特别定义中,副作用将出现两次。
主要是由于#define定义的内容将会直接复制粘贴在内容处。
22,23行的输出也说明了这点
zhy@desktop:~/doublemint/test$ ./test
MAX = 14
MAX*2 = 18
MAX = 16
MAX*2 = 256
MAX_ADJUST = 16
MAX_ADJUST*2 = 32
0
0
2
4