颜林林的个人网站

Linlin Yan's Personal Website

分享搞笑代码(续)

2007-10-03 12:42

还是上次在comp.lang.c++上看到的那个关于用C++写出仿 BASIC 的代码的话题,后来竟然又出现一段模拟 GOSUB 和 RETURN 的代码,让我看后几乎瞠目结舌,于是再转过来续一下(这段代码用了gcc的一个扩展关键词__label__):

#include <list>
#include <stdio.h>

std::list<void*> GosubStack;
void B_ERROR(int e) { throw e; } // for reporting errors

#define B_GOSUB(label) \
{ __label__ gosub_return; GosubStack.push_back(&&gosub_return); \
    goto label; gosub_return:; }
#define B_RETURN() \
{ if (GosubStack.empty()) B_ERROR(2);/* RETURN WITHOUT GOSUB*/ \
    else { void* ret = GosubStack.back(); GosubStack.pop_back(); \
        goto *ret; } }
#define B_RETURN_TO(label) \
{ if (GosubStack.empty()) B_ERROR(2);/* RETURN WITHOUT GOSUB*/ \
    else { GosubStack.pop_back(); goto label; } }

int main()
{
    B_GOSUB(root);
    puts("0");
    goto owa;
root:
    puts("1");
    B_GOSUB(beg);
    puts("2");
beg:
    puts("3");
    B_GOSUB(wan);
    puts("4");
    B_GOSUB(too);
    puts("5");
wan:
    puts("6");
    B_RETURN();
too:
    puts("7");
    B_RETURN_TO(wan);
owa:
    return 0;
}

程序输出结果: 1 3 6 4 7 6 2 3 6 4 7 6 0.

注:特别是其中还模仿了一个Basic中超级 spaghetti 的语句:B_RETURN_TO,对应Basic里的 return label语句(在Basic里,竟然可以在子程序里面返回到指定的行号,而不一定是调用子程序的地方!)

评论(备份自LiveSpace):

  • 2007-10-07 - 忘: 不懂,不過踩個腳印。氣死我了,紫光輸入法被大瘋,只能輸入繁體了,我現在想掐他的脖子。