孟岩ID:myan
[修改头像]
1552954次访问,排名6好友1人,关注者32
总是在思考存在的问题
myan的文章
原创 146 篇
翻译 0 篇
转载 3 篇
评论 5196 篇
最近评论
lschou520:怎么会忘记印度、日本和欧洲呢?
daijunhua:支持,中华儿女,互相护持地走!
ranzj:我只抱怨自己的努力不够。
ranzj:我毫不怀疑 SilverLight 是个“钱”途无量的玩意儿。
winvc:还有 之前已经看到过一篇署名孟岩的文章了 也是自称学计算机的 在MOP发的文章 题目是《不知名的程序员写给想学编程的朋友》(最后署名前还特别声明了下自己是初中文化全靠自学的 大哥 这样的人全国有几千万 没几个比你这种货色差的)

那文章是看的我想吐 不知道是你还是重名了 不过咋跟你这篇文章风格这么像呢 都是不懂 逻辑混乱 瞎喷
你是自己想不明白问题 但认为自己想……
软件项目交易
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes
文章分类
收藏
    相册
    测试
    友情链接
    老赵的博客
    存档

    原创 C语言宏定义中的一个奇技淫巧

    新一篇: Functional Programming应译为“泛函程序设计”

    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

     


     

    发表于 @ 2004年04月27日 14:27:00|评论(loading...)|编辑

    旧一篇: 日军偷袭珍珠港的一些细节——兼评1970和2001年版电影

    评论

    #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)
    行不行?
    #周星星 发表于2004-06-02 08:45: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.*
    不好意思, ? : 式不能用。更正一下。
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 孟岩