2011-09-14 9 views
4

AlchemyはC++のコンパイルをサポートしていますが、STLを使用すると問題が発生します。ほとんどの場合problem with std::stringが原因です。奇妙なのは、アルケミーがGNU libstd++ v3.4.6を使用しているようだということです。 GNUのSTLではstd :: stringが壊れているとは考えにくいです。AlchemyでSTLを使用する

誰もこの問題の回避策を見つけましたか? STLのないC++は水なしの魚のようです。

答えて

5

問題はSTL自体ではありません。 std::stringのGNU実装は、スレッドセーフな関数__gnu_cxx::__exchange_and_add__gnu_cxx::__atomic_addを使用して参照カウントされます。問題は__exchange_and_add/__atomic_addが壊れていることです。

解決策は、これらの機能を適切に実装してSTLを再構築することです。

幸いにも、Alchemyディストリビューションは私たちのためにいくつかのブレッドクラムを残しています。それを行う方法を教えてくれるれ、$ALCHEMY_HOME/avm2-libc/READMEを参照してください:

通常
The sources used to build avm2-libstdc++.l.bc can be downloaded here: 
    http://download.macromedia.com/pub/labs/alchemy/alchemy_gnucpp3-4library_121008.zip 

To build avm2-libstdc++.l.bc: 
cd $ALCHEMY_HOME/avm2-libc 
unzip alchemy_gnucpp3-4library_121008.zip 
mv lib/avm2-libstdc++.l.bc lib/avm2-libstdc++.l.bc.OLD 
make 

You should *not* run achacks prior to using these building this library with make. 
The Makefiles provided have been preconfigured to use LLVM directly where needed. 

私は++ libstdにatomic_add __exchange_and_add/__の実装を見つけることを期待したい($ALCHEMY_HOME/avm2-libc/lib/avm2-libstdc++.l.bc)、しかし、彼らはlibcの中で定義されているいくつかの理由($ALCHEMY_HOME/avm2-libc/lib/avm2-libc.l.bc)のために。

なぜこのようなことがわかりませんが、プロトタイプが保存されているatomicity.hをハッキングすることで回避できます。 alchemy_gnucpp3-4library_121008.zip開梱後、あなたは atomicity.hファイルを編集する必要がありますことに注意してください:

ここ
  • $ALCHEMY_HOME/avm2-libc/include/c++/3.4/bits/atomicity.h
  • $ALCHEMY_HOME/avm2-libc/libstdc++/include/bits/atomicity.h

はコードです:

/* 
    * __exchange_and_add and __atomic_add are broken in Alchemy's libc. 
    * Replace them with functioning implementations. This isn't 
    * cross-platform, but this codebase is only compiling for Alchemy anyway. 
    */ 
    #define __exchange_and_add(x,y) __exchange_and_add_fix((x),(y)) 
    #define __atomic_add(x,y) __exchange_and_add_fix((x),(y)) 

    /* 
    * Correctly implement __exchange_and_add. It's not thread-safe, 
    * but Alchemy isn't threaded, so we should be ok. 
    */ 
    inline _Atomic_word __exchange_and_add_fix(volatile _Atomic_word* __mem, int __val) { 
    int orig= *__mem; 
    (*__mem)+= __val; 
    return orig; 
    } 

再構築されたSTLが動作することを確認するために実行するテストコードを次に示します。

#include <cstdio> 
#include <string> 
#include <map> 
#include <fstream> 
using namespace std; 

void string_test() { 
    string s1; 
    string s2; 

    s1 = "a"; 
    s2 = s1; // copy constructor 
    s1 = "b"; 

    // use your favorite TRACE function here 
    printf("s1= %s \n", s1.c_str()); // expected: "b", actual: "b" 
    printf("s2= %s \n", s2.c_str()); // expected: "a", actual: "b", ERROR 
} 

void map_test() { 
    map<string, int> test_map; 

    test_map["test1"]= 1;  
    test_map["test2"]= 2; 
    test_map["test3"]= 3;  

    string tmp= "test1"; 
    printf("%s : %d \n", tmp.c_str(), test_map[tmp]); 
} 

void ifstream_test() 
{ 
    std::ifstream in("test.txt"); 

    // ERROR 1: 
    // Trying to seek file throws an error: 
    // Error #1006: value is not a function. 
    // at: basic_filebuf::char_traits::seekoff 
    in.seekg(0, std::ios::end); 
    int length = in.tellg(); 
    in.seekg(0, std::ios::beg); 
    printf("File Length: %d \n", length); 

    while(in.good()) { 
     char buffer[512]; 

     // ERROR 2: 
     // RangeError: Error #1125: The index 1092156 is out of range 721. 
     // at basic_filebuf::char_traits::underflow::work() 
     in.getline(buffer, 512, '\n'); 

     printf("buffer= %s \n", buffer); 
    } 
} 

int main() { 
    string_test(); 
    map_test(); 
    ifstream_test(); 

    return 0; 
} 

再構築されたSTLは、mapifstreamといういくつかの関連する問題を修正しているようです。

+0

この問題は私がAlchemyを放棄した理由でした。共有してくれてありがとう。 – Gunslinger47

+0

@ Gunslinger47:もしあなたがSTLを再構築しているなら、Alchemyをもう一度使うことができるようです。あなたが他のいくつかの技術に移行しなかったと仮定します。 :) – paleozogt

関連する問題