LINUX.ORG.RU

Google профинансирует работу над Rust for Linux

 , ,


0

4

Компания оплатит год работы Мигеля Охеда (Miguel Ojeda) над его проектом Rust for Linux. Работа будет вестись в рамках проекта Prossimo под эгидой организации ISRG (Internet Security Research Group) — учредителя проекта Let's Encrypt.

По данным Microsoft около 70% всех уязвимостей, описанных в CVE, вызваны небезопасной работой с памятью. Написание на Rust таких компонентов, как драйверы устройств, может снизить риск появления уязвимостей.

>>> Подробности



Проверено: xaizek ()
Последнее исправление: xaizek (всего исправлений: 4)

Ответ на: комментарий от aist1

Так допишем, какие проблемы?))

Нет, священная кодовая база же.

Это же каждую функцию через которую указатель пробегает надо будет аннотировать, а потом не дай бог дальше потянет.

Короче, мой поинт в том, что люди, которых «задрал С++», но есть накопленная кодовая база, которую не хочется терять, могут пойти в сторону создания собственных анализаторов кода, вместо перехода на совсем другой язык без обратной совместимости.

Или они могут создать новый язык (уже собственно). В котором выкинут ненужное и сделают по-человечески нужное. Старый код просто вызывать, а по мере необходимости существенных изменений переписывать части на новый. А любители старого пусть пытаются скрестить ужа с ежом.

khrundel ★★★★
()
Ответ на: комментарий от aist1

запилить линейные типы в С++ в виде плагина для Clang

Просто уточнить, спрошу: а ты понимаешь, что по сути ты создаёшь новый язык, а не просто дополнительную тулзу для цпп?

unC0Rr ★★★★★
()
Ответ на: комментарий от khrundel

Это же каждую функцию через которую указатель пробегает надо будет аннотировать, а потом не дай бог дальше потянет.

Зачем? Досточно аннотировать класс-обертку. И любое использование этого класса будет проверяться валидатором.

а по мере необходимости существенных изменений переписывать части на новый

Не работает на практике. Кроме того, С++ — совсем не мертвый язык. На нем постоянно появляется много всего нового. Замучаешься «переписывать». Так с Java уже произошло.

aist1 ★★★
()
Ответ на: комментарий от unC0Rr

Просто уточнить, спрошу: а ты понимаешь, что по сути ты создаёшь новый язык, а не просто дополнительную тулзу для цпп?

Давай я тоже уточню, потому что я тут несколько абъюзаю термин «линейные типы», простоты ради понимая их в широком смысле.

Под линейными типами здесь я понимаю дополнительную систему ограничений на использование типа. Например, та же семантика исключительного владения (unique_ptr на стероидах). Или ограничение на последовательность вызова методов (close() должен быть вызван до деструктора) и т.п.

Я не уверен, что система типов Rust позволит делать вот это вот всё. Там, вроде как, не совсем линейные типы.

Здесь же можно сразу заложить возможность высокоуровневой семантики использования. В Rust тоже можно, комбинируя обертки, строить сложные протоколы использования. Но я не уверен, что это будет выглядеть «красиво» с точки зрения человека. Нужно посмотреть.

Короче, линейные типы, которые я здесь имею в виду, не создают новой семантики типов, а лишь накладывают ограничения на существующую семантику (ограничивают использование). Я не считаю это созданием нового языка.

aist1 ★★★
()
Ответ на: комментарий от khrundel

стабильный компилятор С++ это не поддерживает

Что такое стабильный компилятор?

latest stable?

Сейчас это gcc 11.1 и clang 12, правильно?

Или тот который, например, в старом дебиане? Тогда стабильный компилятор Rust это Rust 1.34, верно?

fsb4000 ★★★★★
()
Ответ на: комментарий от kvpfs

Типичный фанат сишечки, зашкаливающее самомнение, а сам - дурачок. Это ж додуматься надо, гордиться тем что скачешь по засранному полю, заранее зная где лепёшки. То что ты в проекте юзаешь - это как бы твоё дело, ты можешь и память маллоком выделять. Но факт остаётся фактом, 2 енума, плохой и исправленный. Плохой выкинуть нельзя, чтоб старый код компилялся, исправить нельзя, вот и добавили второй. Приходится держать в голове особенности, не имеющие никакого практического смысла кроме удовлетворения атавизмов языка. Кстати, чисто ради прикола напоминаю: enum class изменяет 2 свойства старых енумов. Эти 2 свойства никак не связаны между собой, ну кроме того что оба были ошибками дизайна. Таким образом разработчики языка C++ тоже любят подход «сделаем новое, разом исправив всё». Они и не подозревают, что фанаты их на 100 раз перелатанного поделия считают что так нельзя.

khrundel ★★★★
()
Ответ на: комментарий от fsb4000

Что такое стабильный компилятор?

Это может быть всё что угодно вплоть до gcc3. Решать будет самый бородатый чувак в проекте. А чем старше проект, тем больше там UB, которое мешает компилятор обновить. Ты не понял мой поинт, он в том, что лайфтаймы, даже если они появятся в плюсах, использоваться не будут ещё лет 10. К тому моменту Расту будет уже лет 20, бороды у хипсторов поседеют, синтаксис уже будет привычным, и кому тогда эти лайфтаймы в плюсах реально будут нужны? Чтоб в 30летнем легаси-проекте эти лайфтаймы прописывать?

khrundel ★★★★
()
Ответ на: комментарий от khrundel

Решать будет самый бородатый чувак в проекте

Понятно. Просто напомню, что LLVM поддерживает только последнюю версию, сейчас 12. То есть clang 11.x уже EOL.

gcc поддерживает 3 последние ветки: gcc 11, 10, 9. То есть gcc 8.x уже EOL.

Наркоманы могут пользоваться чем угодно, на их мнение плевать. Серьёзные компании не используют EOL продукты.

fsb4000 ★★★★★
()
Ответ на: комментарий от khrundel

даже если они появятся в плюсах, использоваться не будут ещё лет 10

По моим наблюдениям, отставание сейчас где-то года на три в среднем, и постепенно сокращается. Т.е. сейчас С++17 стал уже нормой для библиотек.

У меня в Мемории, например, код разделен на две части. Во «внутренней» части можно использовать С++20. В интерфейсной — С++14. Между ними — Pimpl.

Я думаю, что твой сценарий (10 лет) описывает какой-то исключительный случай, на который не стоит ориентироваться.

aist1 ★★★
()
Ответ на: комментарий от khrundel

Мне тебе больше нечего добавить. У тебя просто нет опыта реальной разработки и в голове какая-то модная пропаганда. Оба энума нужны. Ты можешь по такой схеме до чего угодно докапаться - вон ввели std::variant, значит union было ошибкой дизайна! А я вот сейчас отказался от variant’a в пользу union’a ибо удобней будет для конечного user’a (не надо будет прописывать длинный шаблонный тип при получении члена). Все, сегодня тебе больше не отвечаю.

kvpfs ★★
()
Ответ на: комментарий от aist1

и я решил, что проще запилить линейные типы в С++ в виде плагина для Clang, чем городить вот это вот всё

При всем уважении сомневаюсь в возможности качественной реализации силами одного человека за приемлемое время.

anonymous
()
Ответ на: комментарий от anonymous

При всем уважении сомневаюсь в возможности качественной реализации силами одного человека за приемлемое время.

Линейные типы это ничто. Делается на обычном С++: https://youtu.be/sN8tI-zleFI

Всего лишь один концепт и дальше компилятор будет всё проверять…

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 1)
Ответ на: комментарий от fsb4000

дальше компилятор будет всё проверять…

Точнее дальше запускаем линтер clang-tidy и он нам проверяет отсутствие use-after-move.

А как говорится

Серьёзные компании не используют EOL продукты.

red75prim ★★★
()
Последнее исправление: red75prim (всего исправлений: 1)
Ответ на: комментарий от anonymous

При всем уважении сомневаюсь в возможности качественной реализации силами одного человека за приемлемое время.

Полностью разделяю твое мнение. «Если хочешь дити быстро — иди один. Если хочешь идти далеко — иди вместе».

Я сейчас на первом этапе. Я создаю прототип дата-центричного дизайна для С++. Это система частных решений для практических задач от создания дата-платформ до разработки специализированных аппаратных акселераторов для ИИ (и не только). Эти задачи таковы, что им очень нужны вот эти вот продвинутые фичи языка, такие как расширенное метапрограммирование и валидация с верификацией. А так же средства «программирования в большом» которые мы имеем в таких языках как Java и Scala, и которые себя отлично зарекомендовали.

Так вот, идея в том, что вот эти вот практические задачи и будут мотивировать язык на развитие в обсуждаемом направлении. И это уже не (только) моя задача. Мне лично и существующих инструментов хватает. А что не хватает, я допишу.

Чтобы два раза не вставать, добавлю по теме. С++ — это, на самом деле, не совсем язык программирования, если смотреть на него с прагматической (а не академической) точки зрения. С++ — это развитый протокол над оптимизирующим компилятором. Последний и является «центром вселенной», а его возможности — определяют пространство применимости (конкретного диалекта) языка.

Мы ждем от С++ не красоты и понятности кода (это не язык программирования в большом), а возможности полностью раскрыть потенциал конкретного компилятора и конкретного железа. Для остального есть Java (безопасно) и Python (красиво).

aist1 ★★★
()
Ответ на: комментарий от anonymous

Щас бы Библию (которую не читал)

Ты то у нас Анон всегда знаешь, что я читаю, когда хожу в сартир, и весь мой род до пятого колена, лично.

Фарисеям конечно его лицо не понравилось)

shpinog ★★★
()
Последнее исправление: shpinog (всего исправлений: 1)
Ответ на: комментарий от aist1

Мы ждем от С++ не красоты и понятности кода (это не язык программирования в большом), а возможности полностью раскрыть потенциал конкретного компилятора и конкретного железа. Для остального есть Java (безопасно) и Python (красиво).

Ты так пишешь, как будто с++ какой-то недосягаемой производительности достиг или выразительности. С\Fortran\Rust\Pascal и тд, раскрывают примерно столько же.

То что С++ лапша днями компилиться, говорит много о раскрытии возможностей компилятора.

shpinog ★★★
()
Ответ на: комментарий от shpinog

Ты то у нас Анон всегда знаешь

Совершенно верно в целом. А в твоём частном случае и подавно. Если поциент кукарекает, что дruсt - это панацея, спасение и манна небесная, то он точно безграмотный балабол в любой области знаний.

anonymous
()
Ответ на: комментарий от anonymous

Совершенно верно в целом. А в твоём частном случае и подавно. Если поциент кукарекает, что дruсt - это панацея, спасение и манна небесная, то он точно безграмотный балабол в любой области знаний.

это панацея, спасение и манна небесная,

Где я это написал или балабол здесь ты.

shpinog ★★★
()
Ответ на: комментарий от leave

а туда уже завезли сборку без скачивания странных «инсталляторов»?

А её когда-то там не было?

Legioner ★★★★★
()
Ответ на: комментарий от shpinog

Где я это написал или балабол здесь ты.

Всё ясно, дристосектант вякает что попало, своих слов не запоминает или просто даже не понимает о чём вообще говорит. Потом прикрывается фразами «я не программер, просто все говорят что раст это хорошо». Лол.

anonymous
()
Ответ на: комментарий от shpinog

С\Fortran\Rust\Pascal и тд, раскрывают примерно столько же.

Яж не против. И эти компиляторы в чем-то хороши. Где они — лучшие, их там тоже используют.

То что С++ лапша днями компилиться, говорит много о раскрытии возможностей компилятора.

Нету такого. Относительно долго — да, но не «днями». Вполне нормально, работать можно. Кому надо, берут себе тредрипперы. У меня R9 5950х. Мог бы и тредриппер взять, но взял FPGA. Сборка Clang у меня идет около 8 минут. Никаких «дней» и близко нет.

aist1 ★★★
()
Ответ на: комментарий от X512

Серьёзно?

Кому и кобыла — невеста.

По сравнению с C++ и Java — красиво.

aist1 ★★★
()
Ответ на: комментарий от aist1

Ну вот ниже твоего сообщения отписался типичный фанат цпп. Ему дали безопасный variant, а он попробовал и плюнул, потому что неудобно, union проще. Я не осуждаю, просто демонстрирую. Или C-style касты, изжит ли этот плохой стиль в 2021? Я к тому, что скорость принятия сильно зависит от удобства

khrundel ★★★★
()
Ответ на: комментарий от aist1

Относительно долго — да,

Да, но всё равно не так быстро как могло. Плюс отсутствие дефолтного пм , что через несколько лет уже будет моветон.

Кому надо, берут себе тредрипперы

Ну здесь не столько вина С++, сколько современных тенденций, когда калькулятор на электроне - удивляться нечему.

Сборка Clang у меня идет около 8 минут. Никаких «дней» и близко нет.

А llvm?

shpinog ★★★
()

везде куда ни глянь направо и налево

корпы навязывают дРуст

ввергая разработчиков несмелых

в вредительства губительный прокруст

Syncro ★★★★★
()
Последнее исправление: Syncro (всего исправлений: 1)

Думаете почему его гугол продвигает раст. А потому что компилятор раста вшивает трояны в ваши бинарники. Так что продолжайте пользоватся этим говном.

anonymous
()
Ответ на: комментарий от shpinog

Так цитата будет

Ну вы в этом самом треде сравниваете пришествие языка раст с Иисусом. И считаете это уместным и отсроумным. Почему бы не сказать объективней? Например: От раста здравомыслящие люди шарахаются, как от грязного и вонючего бомжа. Но если он помоется и обретёт минимальные социальные навыки, то на него может и обратят внимание.

anonymous
()
Ответ на: комментарий от Siborgium

Ну давай, клоун, расскажи нам об основной функции микроскопа под названием std::variant. Для особого цимеса цитирую: А я вот сейчас отказался от variant’a в пользу union’a ибо удобней будет для конечного user’a (не надо будет прописывать длинный шаблонный тип при получении члена). Т.е. речь не идёт даже о каких-то внутренних кишках внутри одного изолированного модуля, где хоть на ассемблерных вставках колхозь. Речь о внешнем интерфейсе, юзеровский код будет получать небезопасные юнионы, сам будет правильно проверять, какой тип ему из него извлекать.

khrundel ★★★★
()
Ответ на: комментарий от khrundel

Для особого цимеса цитирую:

Зачем ты мне цитируешь априори неправильное применение variant’а? Цитируемый персонаж все сделал правильно, перейдя на union + tag.

юзеровский код будет получать небезопасные юнионы

И пусть получает.

расскажи нам об основной функции микроскопа под названием std::variant

Rust 1.49 (комментарий)

У тебя в голове полная каша, ты не отличаешь сишные enum’ы и крестовые, enum и enum class друг от друга, ты не понимаешь, зачем нужен variant, и пытаешься из него сделать ADT. У тебя нет никакого представления о том, как работает С++, но ты уже блеешь что-то в эту сторону. Тебе многократно указали на твое невежство, но ты продолжаешь позориться в комментах, размазывая клоунский грим по лицу.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)
Ответ на: комментарий от khrundel

Интерфейс, но какаое-то элементарное удобство тоже значение имеет, к чему погружать пользователя в какой-то там ливер библиотечный? Сравни сам:

template <int I>
union U {
   Type_1<I> m_type_1;
   Type_2<I> m_type_2;
   type_e type() {return m_type_1.m_t;}
};

void callback(ns::something<4>::union_t &u) {
   switch (u.type()) {
      case ns::e_type_1:
         u.m_type_1;  //use
      case ns::e_type_2:
         u.m_type_2;
   }
}

или

void callback(ns::something<4>::variant_t &v) {
   if (std::holds_alternative<ns::Type_1<4>>(v))
         std::get<ns::Type_1>(v);  //use
   if (std::holds_alternative<ns::Type_2<4>>(v))
         std::get<ns::Type_2>(v);
}

Не думаю, что второй колбэк для юзер симпатичней, он его напугает скорее, а он их должен писать сам.

kvpfs ★★
()
Ответ на: комментарий от kvpfs

Шиза какая-то, ты просто не осилил std::visit. Коллбек с variant это уже полный мрак в плане архитектуры. Так быть не должно.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 3)
Ответ на: комментарий от Siborgium

Шиза какая-то. Если это не взаимодействует с голой сишкой, то union заверни в структурку с конструкторами-деструкторами и соответствующими методами.

А в чем выгода? Я просто не очень понимаю, может и заверну если пойму. Грубо говоря юзер дает колбэк в либу, она его дергает на рзличные события, каждое событие имеет свои данные какие-то (Type_1, Type_2), обычные под структуры. В Type_1 и Type_2 первым членом идет enum, могу читать из любого члена т.к. часть common sequences.

variant в таком случае можно было и оставить, ты просто не осилил std::visit.

Тут не столько во мне дело, хочу максимально просто сделать для использования без лишних хитрых фокусов. Ту ссылку с visit не все осилят мне кажется.

kvpfs ★★
()
Ответ на: комментарий от kvpfs

А в чем выгода?

Кто деструкторы на данные вызывать будет?

без лишних хитрых фокусов

Это не «лишние хитрые фокусы», это С++. То, что ты написал – С с классами.

Siborgium ★★★★★
()
Ответ на: комментарий от kvpfs

Не думаю, что второй колбэк для юзер симпатичней, он его напугает скорее, а он их должен писать сам.

нужно изучать С++. Вариант норм.

В минимальном виде callback выглядит так:

auto callback = [](auto v){use(v);};
std::visit(callback, var);

В чуть большем:

auto callback = overloaded {
            [](auto arg) { std::cout << arg << ' '; },
            [](double arg) { std::cout << std::fixed << arg << ' '; },
            [](const std::string& arg) { std::cout << std::quoted(arg) << ' '; }
        };
std::visit(callback, var);

В полном виде:

auto callback = [](auto&& arg) {
    using T = std::decay_t<decltype(arg)>;
    if constexpr (std::is_same_v<T, int>)
        std::cout << "int with value " << arg << '\n';
    else if constexpr (std::is_same_v<T, long>)
        std::cout << "long with value " << arg << '\n';
    else if constexpr (std::is_same_v<T, double>)
       std::cout << "double with value " << arg << '\n';
    else if constexpr (std::is_same_v<T, std::string>)
       std::cout << "std::string with value " << std::quoted(arg) << '\n';
    else 
      static_assert(always_false_v<T>, "non-exhaustive visitor!");
};
std::visit(callback, var);

или так

struct visitor {
    int operator()(int i) const {
        return i;
    }
    int operator()(const Neg& n) const {
        return -eval(*n.expr);
    }
    int operator()(const Add& a) const {
        return eval(*a.lhs) + eval(*a.rhs);
    }
    int operator()(const Mul& m) const {
        return eval(*m.lhs) * eval(*m.rhs);
    }
};
std::visit(visitor{}, var);

В любом случае не хуже свича.

union норм, когда мы можем по каким-то другим критериям понять какой тип в нём хранится и нам не нужен tag. Как, например, в std::string мы можем понять по значению последнего байта строка на стеке или в куче(так как адрес должен быть выровнен, то при куче будет обязательно 0, а на стеке мы можем присвоить значение последнего байта 1. Чтобы не было UB при проверке(так как мы не знаем какой тип union активный) используем std::bit_cast.

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 4)
Ответ на: комментарий от Siborgium

Кто деструкторы на данные вызывать будет?

Так я же говорю Type_1/2 - обычное POD, там нет ни пользовательский конструкторов, ни деструкторов. Если бы были какие-то строки и вектора, то нужно placement new делать, тогда разумно и сверху что-то надкостылить сверху. Т.е. должно быть достаточно:

union_t u;
u.m_type_2 = Type_2{};
user_callback(u);

не?

kvpfs ★★
()
Ответ на: комментарий от kvpfs

Так я же говорю Type_1/2 - обычное POD, там нет ни пользовательский конструкторов, ни деструкторов.

Не заметил, хорошо.

Siborgium ★★★★★
()
Ответ на: комментарий от fsb4000

Тут по пути вопрос возник - как бы закостылить так, чтобы шаблонный оператор() (аналог default в свитче) попал в один набор перегрузок, а не имел больший приоритет? Ну чтобы обработать только нужное, а остальное проигнорить. Как минимум можно топорно через макрос, но как-то поэлегантней бы

#include <iostream>

using namespace std;
template<class... Ts> struct overloaded : Ts... {
	using Ts::operator()...;
	template <typename T>
		void operator()(T &&) {cout << "generic\n";}
};

int main() {
	overloaded o{[](int){cout << "int\n";}
	};
	o(4);
	o(4.0);
	o("");
	return 0;
}
cout: default
cout: default
cout: default

Думал сделать базовый класс, в нём дженерик(). По идее - все операторы= будут находиться в родителях и должны иметь равный вес, но что-то всё равно не выходит (тут пришлось дедукшн гид добавить)

struct Base {
	template <typename T>
	void operator()(T t) {cout << "generic\n";}
};
template<class... Ts> struct overloaded :  Ts... , Base {
	using Ts::operator()...;
	using Base::operator();
};
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
kvpfs ★★
()
Ответ на: комментарий от kvpfs

Так работает

auto base = [](auto &&) {cout << "gen\n";};
template<class... Ts> struct overloaded :  Ts..., decltype(base) {
	using Ts::operator()...;
	using decltype(base)::operator();
};
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

Странно, что наследование от структуры даёт иной результат

kvpfs ★★
()
Ответ на: комментарий от Siborgium

Зачем ты мне цитируешь априори неправильное применение variant’а? Цитируемый персонаж все сделал правильно, перейдя на union + tag.

Ну как сказать… Конечно правильно в том плане что не стал юзать кривую и неудобную реализацию суммарных типов в плюсах.

Rust 1.49 (комментарий)

Посмотрел твои потуги про «собачка лает гав-гав», что тут сказать, очень мило. Иногда ход мыслей идиота восстановить сложно, но в этот раз я, кажется, догадался. Ты где-то увидел объяснение, зачем нужен std::variant если можно взять базовый класс и потомков. И объясняющий для наглядности переписал стандартный пример полиморфизма «животное говорит» на вариант и визитора, попутно объяснив, что при использовании варианта можно не делать наследниками одного класса, можно не засирать их методами, тем более виртуальными, а специфическое поведение локализовать в том месте где оно нужно. Но так как ты нихрена не понял, у тебя всё спуталось и bark стал и методом класса, чем свёл наглядность к нулю.

Однако это не отменяет факта, что variant - это именно попытка в sum types. Хреновая и кривая, как всё в плюсах, но попытка. А визитор - это такая замена паттернматчингу. Понятно что через жопу сделано, различает варианты только по типу, но никто не мешает завести тип meter с даблом внутри, а потом тип kilogram тоже с даблом внутри и их уже запихивать в variant.

Ну и в чём-то ты прав, устами дурачка глаголит истина: действительно, как это сделано, так лучше sum type делать через tagged union.

Собственно это в очередной раз демонстрирует вектор развития плюсов, они как молодящийся старпёр всё пытаются доказать что ещё могут, как-то, обосравшись в процессе, показывают модный трюк, получают похвалу, мол да, деда, ты ещё огого, после чего уходят дальше заниматься своими дедовыми делами. Реально использовать выученный трюк даже не собираясь. А «умытый» молокосос продолжает заниматься своими, в рамки которых этот трюк органично вписывается и полезен.

khrundel ★★★★
()
Ответ на: комментарий от khrundel

как молодящийся старпёр всё пытаются доказать что ещё могут

Занятно, в каждом растотреде самые фанатичные сектанты люто проецируют собственные страхи и комплексы на недоумевающих собеседников. Совпадение? Не думаю.

anonymous
()
Ответ на: комментарий от anonymous

Занятно, в каждом растотреде самые фанатичные сектанты люто проецируют собственные страхи и комплексы на недоумевающих собеседников. Совпадение? Не думаю.

Каких собеседников, болезный? Ты процитировал сравнение со старпером языка C++ :)

khrundel ★★★★
()
Ответ на: комментарий от anonymous

Ну вы в этом самом треде сравниваете пришествие языка раст с Иисусом. И считаете это уместным и отсроумным. Почему бы не сказать объективней? Например: От раста здравомыслящие люди шарахаются, как от грязного и вонючего бомжа. Но если он помоется и обретёт минимальные социальные навыки, то на него может и обратят внимание.

Перечитай ветку, и всё это увидишь. И речь была не о пришествии, как о чём-то святом, речь была об отношении к новому.

shpinog ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.