儘管Alchemy支持編譯C++,但似乎使用使用STL很麻煩,主要是由於problem with std::string。奇怪的是,鍊金術似乎在使用GNU libstd++ v3.4.6。很難相信std :: string在GNU的STL中被破壞了。使用STL和鍊金術
有沒有人想出了這個問題的解決方法?沒有STL的C++就像沒有水的魚。
儘管Alchemy支持編譯C++,但似乎使用使用STL很麻煩,主要是由於problem with std::string。奇怪的是,鍊金術似乎在使用GNU libstd++ v3.4.6。很難相信std :: string在GNU的STL中被破壞了。使用STL和鍊金術
有沒有人想出了這個問題的解決方法?沒有STL的C++就像沒有水的魚。
問題不在於STL本身。使用線程安全函數__gnu_cxx::__exchange_and_add
和__gnu_cxx::__atomic_add
對std::string
的GNU實現進行引用計數。問題是__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.
通常我希望找到的實現__exchange_and_add/__ atomic_add在libstd ++($ALCHEMY_HOME/avm2-libc/lib/avm2-libstdc++.l.bc
),但出於某種原因,他們在libc中定義($ALCHEMY_HOME/avm2-libc/lib/avm2-libc.l.bc
) 。
我不確定爲什麼會出現這種情況,但我們可以通過hacking 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;
}
這個問題是我放棄鍊金的原因。感謝分享。 – Gunslinger47
@ Gunslinger47:如果你想重建STL,看起來你可能會再次開始使用鍊金術。假設你沒有轉向其他技術。 :) – paleozogt