跨平台宏的写法
(若转载,请注明原出处与作者,作者:Witton)
前段时间在写代码的时候,有一段代码发现用宏比较方便,于是就用宏完成了这段代码,写完之后,看到这段代码是相当的整齐,有一种赏心悦目的感觉。现将之贴出来与大家分享:
1 #define FUNCTION(T,N)\
2 int GetBase##N##Array()\
3 {\
4 return (int)&gCharBaseDataArray->##N;\
5 }
6
7 FUNCTION(int,Exp);
8 FUNCTION(int,LvUpPoint);
9 FUNCTION(int,Str);
10 FUNCTION(int,Dex);
11 FUNCTION(int,Phy);
12 FUNCTION(int,Int);
13 FUNCTION(int,Hp);
14 FUNCTION(int,Mp);
15 FUNCTION(int,Att);
16 FUNCTION(int,Def);
17 FUNCTION(int,Hit);
18 FUNCTION(int,Bang);
19 FUNCTION(int,Dodge);
20 FUNCTION(int,Combo);
21 FUNCTION(int,Speed);
22 FUNCTION(int,MagicDef);
23 FUNCTION(int,MagicHit);
24 FUNCTION(int,MagicBang);
25 FUNCTION(int,AntiAtt);
26#undef FUNCTION ```
27
28
29
30其中gCharBaseDataArray中一个指向结构的指针,这个结构如下:
31
32
33
34```cpp
35typedef struct _SCharBase
36
37{
38 int* Exp[ECT_MAX];
39 int* LvUpPoint[ECT_MAX];
40 int* Hp[ECT_MAX];
41 int* Mp[ECT_MAX];
42 int* Att[ECT_MAX];
43 int* Def[ECT_MAX];
44 int* Hit[ECT_MAX];
45 int* Bang[ECT_MAX];
46 int* Dodge[ECT_MAX];
47 int* Combo[ECT_MAX];
48 int* Str[ECT_MAX];
49 int* Dex[ECT_MAX];
50 int* Phy[ECT_MAX];
51 int* Int[ECT_MAX];
52 int* Speed[ECT_MAX];
53 int* MagicDef[ECT_MAX];
54 int* MagicHit[ECT_MAX];
55 int* MagicBang[ECT_MAX];
56 int* AntiAtt[ECT_MAX];
57}SCharBase; ```
58
59
60
61
62代码写好之后,在VC下编译运行都OK。可不久就有同事说我写的这段代码在Linux下编译不过。shit,我一看,上面的那段代码在Linux下编译居然报错: pasting "->" and "XXX" does not give a valid preprocessing token
63
64于是我就试试用偏移的方式来解决这个问题,将上面的宏定义成如下的样子:
65
66
67
68```cpp
69#define Offset(t, f) ((size_t)(char *)&((t *)0)->f)
70#define FUNCTION(T,N)\
71 int GetBase##N##Array()\
72 {\
73 return (int)((char*)gCharBaseDataArray + Offset(SCharBase,N));\
74 }```
75
76 在VC下编译运行,OK!试试在Linux下编译运行,也OK!可是我感觉这样不爽!仔细看看,想想,Offset宏的参数f在使用的时候是没有加##的,将我写的那个宏也试试不加##,写成:
77
78
79
80```cpp
81#define FUNCTION(T,N)\
82 int GetBase##N##Array()\
83 {\
84 return (int)(gCharBaseDataArray->N);\
85 }```
86
87
88
89在VC下编译运行,OK!在Linux下呢?试试看吧,编译,运行,OK!!!!!
90
91OK,这次的分享就到此结束吧
92
- 原文作者:Witton
- 原文链接:https://wittonbell.github.io/posts/2007/2007-04-30-跨平台宏的写法/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。