2010-12-04 41 views
1

有人可以解釋爲什麼這段代碼不起作用鍵盤? 修改後的版本(虛擬函數)實際工作雖然 -
工作版本 - http://codepad.org/5rRIg5zT
不工作的版本(下) - http://codepad.org/4PO2rBqS
我的意思是,是實際有效的C++或鍵盤編譯出錯?協程演示源/ 2

更新:有另一種工作方式來做到這一點 - http://codepad.org/j6GAKXov 但它不是很自動。

#include <stdio.h> 
#include <stdlib.h> 
#include <memory.h> 

typedef unsigned int uint; 
typedef unsigned short word; 
typedef unsigned char byte; 

#ifdef __GNUC__ 
#define NOINLINE __attribute__((noinline)) 
#else 
#define NOINLINE __declspec(noinline) 
#endif 

#include <setjmp.h> 

enum{ 
    STKPAD=1<<16, 
    STKSAV=1<<10 
}; 

template <typename T> 
struct coroutine { 

    volatile uint state; 
    volatile char* stkptrH; 
    volatile char* stkptrL; 
    jmp_buf PointA, PointB; 
    char stack[STKSAV]; 

    coroutine() { state=0; } 

    NOINLINE // necessary for IntelC + my_setjmp.h 
    void yield(int value) { 
    char curtmp; stkptrL=(&curtmp)-16; // -16 is necessary for MSC 
    if(setjmp(PointB)==0) { 
     state = value; 
     memcpy(stack, (char*)stkptrL, stkptrH-stkptrL); 
     longjmp(PointA,1); 
    } 
    } 

    NOINLINE // necessary for MSC, to avoid allocation of stktmp before setjmp() 
    void call_do_process() { 
    char stktmp[STKPAD]; stkptrH = stktmp; 
    ((T*)this)->do_process(); 
    } 

    uint call(void) { 
    if(setjmp(PointA)==0) { 
     if(state) { 
     memcpy((char*)stkptrL, stack, stkptrH-stkptrL); 
     longjmp(PointB,1); 
     } 
     call_do_process(); 
    } 
    return state; 
    } 

}; 

struct index : coroutine<index> { 

    void do_process(void) { 
    uint a=1; 
    while(1) { 
     yield(a); 
     a++; 
    } 
    } 

} F1; 

struct fibonacci : coroutine<fibonacci> { 

    void do_process(void) { 
    uint a=0,b=1; 
    while(1) { 
     yield(b); 
     b = b + a; 
     a = b - a; 
    } 
    } 

} F2; 

int main(int argc, char** argv) { 

    for(int i=0; i<20; i++) { 
    printf("%i:%i ", F1.call(), F2.call()); 
    } printf("\n"); 

    return 0; 
} 
+0

我收到了一個你在這個問題中發佈的錯誤。你得到了什麼? – 2010-12-04 07:21:10

+0

它可以在windows上使用gcc 4.3 +/intelc/VS,在iPhone上使用gcc 4 – Shelwien 2010-12-04 07:23:56

回答

2

在非工作版本,如果我改變

struct index : coroutine<index> { 

struct indexX : coroutine<indexX> { 

然後它突然編譯(使用GCC)。顯然,在頭文件的某處已經定義了一個'索引',它會干擾你的代碼的索引。

1

謝謝,所以這裏是一個緊湊的版本,確實對鍵盤的工作 - http://codepad.org/6mBAyMhx
有趣的一點是,它實際上出現segfaults有沒有這種noinline始終

#include <stdio.h> // for printf 
#include <memory.h> // for memcpy 
#include <setjmp.h> // for setjmp 
template <typename T> struct coroutine { 
    volatile int state; coroutine():state(0){} 
    volatile char *stkptrH,*stkptrL; jmp_buf PointA,PointB; char stack[1<<10]; 
    void yield(int value) { char curtmp; stkptrL=(&curtmp)-16; if(setjmp(PointB)==0) 
    state=value,memcpy(stack,(char*)stkptrL,stkptrH-stkptrL),longjmp(PointA,1); } 
    __attribute__((noinline)) int call_do_process() { char stktmp[1<<16];stkptrH=stktmp;((T*)this)->do_process();return 0;} 
    int call() {if(setjmp(PointA)==0)(state?memcpy((char*)stkptrL,stack,stkptrH-stkptrL),longjmp(PointB,1):void(0)),call_do_process();return state;} 
}; 

struct Index : coroutine<Index> { void do_process(void) { 
    for(int a=1;;) { yield(a); a++; } 
}} F1; 

struct Fibonacci : coroutine<Fibonacci> { void do_process(void) { 
    for(int a=0,b=1;;) { yield(b); b = b + a; a = b - a; } 
}} F2; 

int main(void) { 
    for(int i=0; i<20; i++) { 
    printf("%i:%i ", F1.call(), F2.call()); 
    } printf("\n"); 
    return 0; 
}