использование STL с алхимией - PullRequest
4 голосов
/ 14 сентября 2011

Хотя Alchemy поддерживает компиляцию C ++, кажется, что использование STL является проблемой, в основном из-за проблемы с std :: string . Странно то, что Алхимия, похоже, использует GNU libstd ++ v3.4.6 . Трудно поверить, что std :: string не работает в STL GNU.

Кто-нибудь нашел какие-нибудь обходные пути для этой проблемы? C ++ без STL - это как рыба без воды.

1 Ответ

5 голосов
/ 14 сентября 2011

Проблема не в STL как таковой.Реализация GNU для std::string подсчитывается с использованием поточно-ориентированных функций __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.

Обычно я ожидаю найти реализации __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).

Я не уверен, почему это так, но мы можем обойти это, взломав 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 исправляет некоторые связанные проблемы с map и ifstream .

...