作者:孟岩 来源:CSDN博客 酷勤网收集 2007-12-09
CII Chap 04中,对于RETURN的宏定义是:
#define RETURN switch(Exception_stack = Exception_stack->prev, 0) default: return
放在如下的代码中:
TRY
/* do something */
if (failed)
RETURN 1;
EXCETPT(Allocation_Failed)
/* Handle allocation fail */
END_TRY
展开之后就是:(暂不考虑TRY的宏定义)
TRY
/* ... */
if (failed)
switch(Exception_stack = Exception_stack->prev, 0)
default:
return 1;
EXCEPT(Allocation_Failed)
...
END_TRY
可以看到,这个宏的唯一目的,就是在return 1之前,执行Exception_stack = Exception_stack->prev语句。
仔细考虑之后可以发现,C语言中其他的结构都不能满足这一条件。如果使用
#define RETURN if(Exception_stack = Exception_stack->prev, 1) return
则在
if (...)
RETURN 1;
else
...
语句中,会导致else的误匹配。
我想到的唯一一个功能相同的语言结构是:
#define RETURN (Exception_stack = Exception_stack->prev, 0) ((void)0) : return
评论
ai-fans 发表于2004-05-01 01:04:00 IP: 61.49.198.*| en, 真的很巧妙 |
XianChou 发表于2004-05-19 00:23:00 IP: 210.82.77.*| #define RETURN(_X) do{if(Exception_stack = Exception_stack->prev, 1) return _X}while(0) |
傻强 发表于2004-05-31 09:54:00 IP: 61.178.108.*| 为什么起这么个文章名 |
周星星 发表于2004-06-02 08:44:00 IP: 218.2.111.*| #define RETURN do( Exception_stack = Exception_stack->prev; return ) while(0) 行不行? |
hanshuifang 发表于2004-06-15 17:44:00 IP: 218.108.42.*| i want to ask : 1. why define RETURN macro instead use code directly? 2. Where else should this macro define helpful? and since i couldn't find out the answer to these two question, so i don't think this skill valuable! |
无名 发表于2004-06-07 13:27:00 IP: 202.105.42.*| #define ACE_RETURN(Y) \ do { \ int __ace_error = ACE_Log_Msg::last_error_adapter (); \ ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \ ace___->set (__FILE__, __LINE__, Y, __ace_error, ace___->restart (), \ ace___->msg_ostream (), ace___->msg_callback ()); \ return Y; \ } while (0) 回复:C语言宏定义中的一个奇技淫巧 |
myan 发表于2004-06-08 15:09:00 IP: 218.247.132.*| 几位朋友的解决方案都不对。因为RETURN是要这样用的 func() { TRY //... // ... RETURN 10; EXCEPT // ... END_TRY } |
周星星 发表于2004-06-09 12:13:00 IP: 218.2.111.*| 佩服! |
xjf 发表于2004-06-22 23:45:00 IP: 218.19.121.*| 可以解析一下,最后一句是什么意思? #define RETURN (Exception_stack = Exception_stack->prev, 0) ((void)0) : return 没看明白 |
ypapa 发表于2004-07-10 11:04:00 IP: 61.51.215.*| CII 是什么?机械工业出的《C语言接口与实现》? |
刘未鹏 发表于2004-08-25 00:34:00 IP: 222.94.3.*| 不知道这样可不可以呢: #define RETURN return Exception_stack = Exception_stack->prev, 例如: #define RETURN return i=0, double f() { int i=0; RETURN 0.99; ^^^^^^^^^ } int main() { double i= f(); std::cout<<i; //outputs 0.99 system("pause"); } |
perl-emacser 发表于2004-09-13 13:53:00 IP: 210.22.158.*| 一种利用macro定义函数的常用方法是: #define foo(_arg) \ {\ statement1;\ statement2;\ ... }while(0) 这个方法已被验证是可行的,可以添加任意多个语句,并且不会带来任何二义性。由于大家都这样用,这个定义也很容易理解,这已经是一种约定俗成的标准,而且linux内核里也是采用这个宏定义标准。它也并不是什么奇技淫巧!!!!! |
赵老师 发表于2004-09-24 17:25:00 IP: 165.170.128.*| 奇技淫巧=奇巧淫技 可是糍粑没有收录,我生怕自己写错了 |
lodge 发表于2004-10-14 05:00:00 IP: 61.183.79.*| #define RETURN switch(Exception_stack = Exception_stack->prev, 0) default: return #define RETURN return Exception_stack = Exception_stack->prev, #define RETURN(_X) do{if(Exception_stack = Exception_stack->prev, 1) return _X}while(0) 这三种都可以,不过前两种好一点,不带参数的,更方便。而第二种在只用RETURN ;这是有语法错误,总的来说第一种最好。 |
peanut 发表于2004-10-14 16:48:00 IP: 218.81.161.*| 其实,尚有一种用for的方法(在我自己的实现里就是用for的,不知道那个编译出的代码更好一些), #define RETURN \ for(Exception_stack = Exception_stack->prev; ;) return 当然,for的妙用还不至于此:) |
agui 发表于2004-11-05 17:00:00 IP: 211.151.91.*| >#define RETURN switch(Exception_stack = Exception_stack->prev, 0) default: return >#define RETURN return Exception_stack = Exception_stack->prev, >#define RETURN(_X) do{if(Exception_stack = Exception_stack->prev, 1) return _X}while(0) >这三种都可以,不过前两种好一点,不带参数的,更方便。而第二种在只用RETURN ;这是有语法错误,总的来说第一种最好。 第二种如果不带返回值,语法会错误。 第三种逼着人用括弧,跟 return 不象。 开始想不明白为什么要用 switch 语句,后来想他可能是要用在只有一个语句的地方。如: if (xxxxx) RETURN y; >#define RETURN (Exception_stack = Exception_stack->prev, 0) ((void)0) : return 冒号起什么作用啊?在C里好象冒号在标号(label)、case语句及:?中才有用,这里起什么作用呢?能编译通过吗? 这一句的前面部分看起来象是函数调用。编了一个程序试试发现通不过编译: $ cat t.c struct s { struct s* prev; } *Exception_stack; #define RETURN (Exception_stack = Exception_stack->prev, 0) ((void)0) : return void f() { RETURN; } int g() { RETURN 0; } 编译信息: $ gcc -c t.c t.c: In function `f': t.c:8: called object is not a function t.c:8: parse error before `:' t.c: In function `g': t.c:13: called object is not a function t.c:13: parse error before `:' PS: 以前以为switch语句必须要有大括号,从这里看来,也可以不要(因为只有return一句?),受教。 |
nydgg 发表于2005-01-12 23:14:00 IP: 218.29.25.*| 又想了几个:),不知能不能用 #define RETURN for (lhs=rhs; ; ) return #define RETURN while (lhs=rhs, 1) return 文章里的好像没写对,修改一下 #define RETURN lhs=rhs, 0? ((void)0) : return 还有 ? : 的 if 式 #define RETURN if (lhs=rhs, 0) ((void)0); else return |
nydgg 发表于2005-01-12 23:24:00 IP: 218.29.25.*| 不好意思, ? : 式不能用。更正一下。 |

