Увидел свет (http://lists.cs.uiuc.edu/pipermail/llvm-announce/2014-Januar...) релиз проекта LLVM 3.4 (http://llvm.org) (Low Level Virtual Machine) - GCC совместимого инструментария (компиляторы, оптимизаторы и генераторы кода), компилирующего программы в промежуточный биткод (http://llvm.org/docs/BitCodeFormat.html) RISC подобных виртуальных инструкций (низкоуровневая виртуальная машина с многоуровневой системой оптимизации). Сгенерированный платформонезависимый псевдокод может быть преобразован при помощи JIT-компилятора в машинные инструкции непосредственно в момент выполнения программы.
Основные новшества (http://llvm.org/releases/3.4/docs/ReleaseNotes.html) LLVM 3.4:- Существенно увеличена производительность генератора кода. При использовании флагов оптимизации "-Os" и "-O2" по умолчанию включена поддержка автоматической векторизации циклов, ранее применяемой только при указании флага "-O3". Также включен по умолчанию представленным в прошлом выпуске новый SLP-векторизатор. - Сборка по умолчанию бэкэнда для использования в качестве целевой платформы GPU семейства R600 (HD2XXX - HD7XXX). Бэкэнд необходим для компилятора шейдеров LLVM, который в свою очередь требуется для открытой реализации стандарта OpenCL;
- Внесены заметные изменения в бэкенд для процессоров PowerPC, положительно повлиявшие на качество кода и скорость сборки;
- Расширены возможности бэкендов X86, SPARC, ARM32, Aarch64 и SystemZ;
- LLVM 3.4 является последним выпуском, который может быть собран компилятором с поддержкой стандарта C++'98, для сборки следующих версий потребуется компилятор, совместимый с C++'11.Основные новшества субпроектов LLVM 3.4:
- Улучшения (http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html) в Clang:
- Обеспечена полная поддержка всех возможностей текущего чернового варианта будущего стандарта C++1y;- В Clang Static Analyzer (http://clang-analyzer.llvm.org/) существенно улучшена поддержка C++, сокращено число ложных срабатываний и расширено число выявляемых ошибок;- В состав включена новая утилита "clang-format", которую можно использовать для автоматического форматирования кода в текстовых редакторах или интегрированных средах разработки, на основе заданного набора правил стилевого оформления кода;- Добавлен экспериментальный альтернативный интерфейс командной строки, обеспечивающий совместимость на уровне опций с компилятором cl.exe из состава Visual Studio, который может применяться для упрощения миграции проектов на Clang без переработки сборочных сценариев;- При использовании флага "-O4" теперь не включается оптимизации на стадии компоновки (link-time optimization), для которой следует явно указать флаг "-flto", применяемый при любом уровне оптимизации.
Из параллельно развивающихся проектов, основанных на LLVM, можно отметить:
- KLEE (http://klee.llvm.org/) - символьный анализатор и генератор тестовых наборов;- Runtime-библиотека compiler-rt (http://compiler-rt.llvm.org/);
- llvm-mc (http://llvm.org/releases/2.6/docs/ReleaseNotes.html#mc) - автогенератор ассемблера, дизассемблера и других, связанных с машинным кодом компонентов, на основе описаний параметров LLVM-совместимых платформ.
- VMKit (http://vmkit.llvm.org/) - виртуальная машина для Java и .NET;
- Реализация функционального языка программирования Pure (http://pure-lang.googlecode.com/);
- LDC (http://www.dsource.org/projects/ldc) - компилятор для языка D;
- Roadsend PHP (http://code.roadsend.com/rphp) - оптимизатор, статический и JIT компилятор для языка PHP;
- Виртуальные машины для Ruby: Rubinius (http://rubini.us/) и MacRuby (http://www.macruby.org/);
- LLVM-Lua (http://code.google.com/p/llvm-lua/)
- FlashCCompiler (http://llvm.org/devmtg/2008-08/Petersen_FlashCCompiler.pdf) - средство для компиляции кода на языке Си в вид пригодный для выполнения в виртуальной машине Adobe Flash;
- LLDB (http://lldb.llvm.org/) - новая (http://www.opennet.me/opennews/art.shtml?num=26907) модульная инфраструктура отладки, использующая такие подсистемы LLVM как API для дизассемблирования, Clang AST (Abstract Syntax Tree), парсер выражений, генератор кода и JIT-компилятор. LLDB поддерживает отладку многопоточных программ на языках C, Objective-C и C++; отличается возможностью подключения плагинов и скриптов на языке Python; демонстрирует экстремально высокое быстродействие при отладке программ большого размера;
- emscripten (https://github.com/kripken/emscripten/wiki) - компилятор биткода LLVM в JavaScript, позволяющий преобразовать для запуска в браузере приложения, изначально написанные на языке Си. Например, удалось запустить Python, Lua, Quake, Freetype;
- sparse-llvm (https://github.com/penberg/sparse-llvm) - бэкенд, нацеленный (http://www.opennet.me/opennews/art.shtml?num=31636) на создание Си-компилятора, способного собирать ядро Linux.
- Portable OpenCL (http://www.opennet.me/opennews/art.shtml?num=32092) - открытая и независимая реализация стандарта OpenCL;
- CUDA Compiler (http://www.opennet.me/opennews/art.shtml?num=33800) - позволяет сгенерировать GPU-инструкции из кода, написанного на языках Си, Си++ и Fortran;
- Julia (http://www.opennet.me/opennews/art.shtml?num=33315) - открытый динамический язык программирования, использующий наработки проекта LLVM.
URL: http://lists.cs.uiuc.edu/pipermail/llvm-announce/2014-Januar...
Новость: http://www.opennet.me/opennews/art.shtml?num=38798
йо, ма йо, я еще 3.3 не успел собрать, а уэе 3.4 есть
собирай на компьютере - это быстрее.
> Features
> JIT compile Lua scripts to native code using LLVM's JIT engine. JIT supports x86, x86_64, PowerPC 32/64 processors.
> Compile Lua scripts to native executables.
> Cross-compile Lua scripts to native executables/modules a different target then the host.Торт!
> ... Сгенерированный платформонезависимый псевдокод может
> быть преобразован при помощи JIT-компилятора в машинные инструкции
> непосредственно в момент выполнения программы. ...Псевдокод — язык описания алгоритмов, использующий ключевые слова языков программирования, но опускающий подробности и специфический синтаксис. Псевдокод — (в неформальной лексике) байт-код, машинно-независимый код низкого уровня, генерируемый компилятором и исполняемый виртуальной машиной.
Взято отсюда: http://ru.wikipedia.org/wiki/%D0%9F%D1%8...
Доколе будет распространятся эта гнилая "неформальная лексика" ?
> Доколе будет распространятся эта гнилая "неформальная лексика" ?Почему вообще не использовать англоязычные термины, если только "русское" слово биткод не кажется более лучше. Например, в медицине/биологии используются термины на мертвом языке (латынь, если кто не понял) и никто в мире вроде не жалуется на непатриотичность, все всех понимают - универсальный язык. Почему в IT нельзя использовать универсальную терминологию на почти мертвом языке и не ломать голову. Помнится, одна страна уже вроде попыталась в патриотически-националистическом порыве перевести все на рiдну мову, было смешно.
Но свой комментарий ты всё-таки написал по русски?
> Но свой комментарий ты всё-таки написал по русски?Да вы тут все демагоги недоношенные.
А на каком языке я его должен был написать? Не тупи.
на таком на котором пишут новости? не?
Таки посмотрите и где Ваша медицина, и где IT ;)
Таки IT будет там же, где на украине медицина, если всю терминологию перековеркать.
таки да
Longus penis basis vita
Хреновый там JIT.
Годный JIT у LuaJIT.
> Хреновый там JIT.
> Годный JIT у LuaJIT.Ну, перепиши и прославишься.
Так зачем, LuaJIT уже есть.
> Так зачем, LuaJIT уже есть.так тому анонимусу же главное — «прославиться». поэтому он ничего и не пишет: на «приветмирах» не прославишься, а для сложных проектов нормально работающий мозг нужен.
>> Features
>> JIT compile Lua scripts to native code using LLVM's JIT engine. JIT supports x86, x86_64, PowerPC 32/64 processors.
>> Compile Lua scripts to native executables.
>> Cross-compile Lua scripts to native executables/modules a different target then the host.
> Торт!это не торт, это куча мусора. чем оно лучше LuaJIT — тем, что надо весь монструозный llvm с собой таскать, да ещё и c++ компилятор, чтобы LLVM собрать? тьфу.
> В Clang Static Analyzer существенно улучшена поддержка C++,
> сокращено число ложных срабатываний и расширено число выявляемых ошибок;
char *str_port;
char *str_p;str_p = (char *) calloc(1, 5);
str_port = str_p; // Вот тут оно матерится, что "Value stored to 'str_port' is never read"
str_port = strpbrk(fulladdr, ":");
str_port++;
port = (uint16_t) strtol(str_port, NULL, 10);free(str_p);
Разве это не так?
> Разве это не так?А что не видно?
Нет, ты в той строке присваиваешь значение, а в следующей затираешь его. Или я где-то не прав?
> Value stored to 'str_port' is never readпопробуй еще раз перевести и с равни с тем о чем ты говоришь.
Переменные могут быть неинициализированы.
Он бы ещё на это ругался:
int a, b=5;
a=b+1; // и писал бы — а потерялась, ай-ай-ай.
ну ты тоже гугл транслейтом воспользовался? написано же - запизанное значение( не переменная ) не читается.а пример твой вообще бред.
Да похеру что, тут важно где.
Хорошь флэйм разводить.
Не прав.
Неинициализированному указателю присваивается значение.
Это штатная ситуация. И таких много.
2 раза подряд присваиваем.
Где это она штатная? Я ещё понял бы двойное присваивание если одно присваивание выполнялось при условии каком-то(то есть тут было ветвление), а так бессмысленное действие.
Где два?
Вначале объявляем (значение при этом не определено). Потом присваиваем.
Вот если бы я не определённую переменную захотел использовать, вот тогда и матюгался.Зыж
И не нужно свои стандарты какие-то выдумывать.
Полно подобного кода. Например пустой двусвязный список, 2-а указателя инизиализируются на самого себя. И т.д.
Я могу хоть 100500 указателей с одним и тем же значением понасоздавать.
А вот читать 100500 таких ложных срабатываний... так между ними что-то важное и пропустишь.
char *str_port; // объявили
char *str_p;str_p = (char *) calloc(1, 5);
str_port = str_p; // положили значение
str_port = strpbrk(fulladdr, ":"); // затёрли значение ни разу не использовав
str_port++;
port = (uint16_t) strtol(str_port, NULL, 10);free(str_p);
Вот где "положили" (4-я строка), там он и отматюгался (если верить павлинуху).
А вот там где "затёрли", павлинух молчит (компилер, если ему верить, тоже).
См. исходное сообщение.
Ну так уж порешили те кто анализатор писал, что бы ругалось на ту строку в которой мы выполнили пустое действие. Что не лишено логики.
Ну да! А если присваивание (которое второе) будет на 100500 строк кода ниже? Или в другом файле вообще? А оно мне будет на первое ругаться?
Не-не.
Для начала когда мы выйдем за пределы локальной области видимости(указатели начнут путешествовать между функциями), то вообще оно определит этот случай или нет и даже если определит как оно ругнётся вопрос опять же из разряда нужно проверить.
Для начала вернитесь к указанному примеру.
А когда (и если) поймёте почему не должен матюгаться, тогда и следующие примеры рассмотрим. :D
Вот и возвращайся если до тебя не дошло.
Хамить не стоит, юноша.
В той строке ошибки нет, и вы уже это поняли. Но ослиное упрямство и юнешеский максимализм не позволяют вам это признать.
> Ну да! А если присваивание (которое второе) будет на 100500 строк кода
> ниже? Или в другом файле вообще? А оно мне будет на
> первое ругаться?
> Не-не.Так, мужики, мне нужна эта фича, чтоб сохранить адрес выделенной области!
Потому как после всех манипуляций с адресами, во free попадёт хрен знает чо.
#include <stdlib.h>int main(void)
{
char *a;
char *b;
b = (char *)calloc(1, 5);
a = b;
b++;
free(b);return 0;
}Потому как, если я сделаю
#include <stdlib.h>int main(void)
{
char *b;
b = (char *)calloc(1, 5);
b++;
/*
... и остальные дела с указателями...
*/
free(b); // тут будет invalid pointerreturn 0;
}
>Так, мужики, мне нужна эта фича, чтоб сохранить адрес выделенной области!В чем проблема?
На такой код не будет ругаться уже. Неужели разницы не видишь?
>>Так, мужики, мне нужна эта фича, чтоб сохранить адрес выделенной области!
> В чем проблема?
> На такой код не будет ругаться уже. Неужели разницы не видишь?На какой такой? На первый - ругается, на второй - крэшдампится. :)
>>>Так, мужики, мне нужна эта фича, чтоб сохранить адрес выделенной области!
>> В чем проблема?
>> На такой код не будет ругаться уже. Неужели разницы не видишь?
> На какой такой? На первый - ругается, на второй - крэшдампится. :)На этот
int main(void)
{
char *a;
char *b;
b = (char *)calloc(1, 5);
a = b;
a++;
free(b);return 0;
}Что говорит? Только без теории давай. Не поверю, что ругается.
Интересно на какой день до павлина дойдёт?
Делайте ставки :)
> Интересно на какой день до павлина дойдёт?
> Делайте ставки :)На десятый.
>На какой такой? На первый - ругается, на второй - крэшдампится. :)Он не ругается - он честно предупреждает, что оптимизатор (или процессор при out of order execution) обнаружив бесполезные действия может их выкинуть. А вы наивный будете полагать, с чего бы он опять крешдампится.
А что, разве clang анализатор ругается на этот код (первый листинг)?Например "gcc -Wall" будет ругаться только если убрать строку "a++;":
main.c:5:15: warning: variable ‘a’ set but not used [-Wunused-but-set-variable]
char *a;
^
> А что, разве clang анализатор ругается на этот код (первый листинг)?угу, точнее, шланг молчит. Орёт Анализатор, про него весь шухер. :)
Ой блин, там не тот код... Ща найду оригинал
----
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>int main(void)
{
char *a;
char *b;
uint16_t port;
char *fulladdr = "127.0.0.1:8888";b = (char *)calloc(1, 5);
a = b;
a = strpbrk(fulladdr, ":");
a++;
port = (uint16_t)strtol(a, NULL, 10);
free(b);printf("%zu\n", port);
return 0;
}
Присваивание a=b лишнее, сначала вы присваиваете а адрес строки в b а затем, сразу же, присваиваете адрес символа ":" в строке fulladdr, ругается оно потому, что вы присвоили значение переменной, и не использовав затерли. Вот на то значение которое вы не использовали оно и ругается.
> Присваивание a=b лишнее,ПАТАМУ ША ЭТО ПРИМЕР, ВСЁ НАМНОГО СЛОЖНЕЕ!
И да, зачем в этом примере переменная b я не пойму, она только создается, выделяться память, память освобождается, и все никакой полезной работы связанной с переменной b.Эквивалент:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>int main(void)
{
char *a;
uint16_t port;
char *fulladdr = "127.0.0.1:8888";a = strpbrk(fulladdr, ":");
a++;
port = (uint16_t)strtol(a, NULL, 10);printf("%zu\n", port);
return 0;
}
На самом деле эту переменную компилятор игнорирует, так как с ней не производится ни одного действия, так что если даже посмотреть на вывод objdump, её и признаков там в помине не будет.
> На самом деле эту переменную компилятор игнорирует, так как с ней не
> производится ни одного действия, так что если даже посмотреть на вывод
> objdump, её и признаков там в помине не будет.ПАТАМУ ША ЭТО ПРИМЕР, ВСЁ НАМНОГО СЛОЖНЕЕ!
> И да, зачем в этом примере переменная b я не пойму,ПАТАМУ ША ЭТО ПРИМЕР
>> И да, зачем в этом примере переменная b я не пойму,
> ПАТАМУ ША ЭТО ПРИМЕРСжалюсь ужо над человеком :)
>a = b;
a++; #Ta-da!
>a = strpbrk(fulladdr, ":");И не должен после этого ругаться. Надеюсь понятно теперь.
Полно подобного кода. Например пустой двусвязный список, 2-а указателя инизиализируются на самого себя. И т.д.
В данном примере переменные не существуют вне функции они локальны. В случае списка который ты описал они никуда не денутся и срабатывания не должно быть по логике.В данном коде очень просто определяется факт того что происходит пустое действие. Вот как анализатор поведёт себя на сложном примере(ну хоть бы список о котором вы говорили, вопрос более интересный).
Бред.
Я не могу создать двусвязные списки локально?!
Сферический конь в вакуме мы не проанализируем. Пример кода напиши и засунь в LLVM. При этом если ты его локально создаш, то в случае если по логике реально будет сказать что действие не нужное(а если список за пределы функции не уходит, то определить это проше простого), то оно тебе и скажет.
В общем хватит флэймить. Пример уже есть. И ругаться он там не должен.
Нету флейма. И с какого перепуга не должен? Если тебе идеологически не нравится что он ругается на строку в которой мы делаем пустое действие, а не на строку где мы затираем переменную, то это твои проблемы.
Вопрос в том, будет ли он ругаться в случае инициализации переменой или нет. В приведенном Павлинухом примере лучше бы ругался, но если я например, проинициализирую указатель не валидным значением, а потом эта шляпа начнет ругаться, то не айс.
> Нету флейма. И с какого перепуга не должен? Если тебе идеологически не
> нравится что он ругается на строку в которой мы делаем пустое
> действие, а не на строку где мы затираем переменную, то это
> твои проблемы.Ну так и скажи - "Я тупее компилятора, Шланг спасёт меня!!!"
>> Нету флейма. И с какого перепуга не должен? Если тебе идеологически не
>> нравится что он ругается на строку в которой мы делаем пустое
>> действие, а не на строку где мы затираем переменную, то это
>> твои проблемы.
> Ну так и скажи - "Я тупее компилятора, Шланг спасёт меня!!!"У тебя проблемы с диалектикой.
LLVM всё правильно ругаецца. Нефиг 2 раза подряд ЗАПИСЫВАТЬ значение указателя.
> LLVM всё правильно ругаецца. Нефиг 2 раза подряд ЗАПИСЫВАТЬ значение указателя.Чо????
str_p = (char *) calloc(1, 5);
str_port = str_p; // Вот тут оно матерится, что "Value stored to 'str_port' is never read"
str_port = strpbrk(fulladdr, ":"); // ниразу не считав str_port мы его перезаписалиА что непонятно?
Сначала в str_port засунули 1 указатель, а потом нифига с ним не делая перезаписываем его. Получается что строка str_port = str_p; бессмысленна и её надо выкинуть или выполнять какие-то действия с указателем.
В str_port ничего не запихивали, прикинь.
Он до этого имеет неопределённое значение.И это наводит на мысль, что? Он бы не матюгнулся, если бы я его начал использовать?
Вот тогда было б хренова.
Павлуша, проверь что скажет, если эту строку закомментить, плс.
> В str_port ничего не запихивали, прикинь.Это указатель!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4 (8) байт!!! ВСЁ, НЕТ ТАМ БОЛЬШЕ НИЧЕГО!
> Павлуша, проверь что скажет, если эту строку закомментить, плс.Молчит, всё нормально.
> >В str_port ничего не запихивали, прикинь.
>Это указатель!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4 (8) байт!!! ВСЁ, НЕТ ТАМ БОЛЬШЕ НИЧЕГО!>Иииииииии? :D
>>Павлуша, проверь что скажет, если эту строку закомментить, плс.
>Молчит, всё нормальноНу и слава Богу.
С рождеством.
> Иииииииии? :DГладиолус.
Лопата.
Указатели по-умолчанию тоже не инициализируются.
Усё.
> Лопата.[censored]
Зыж
А если и следующую?
До инкремента?
Будет увеличивать неинициализированный указатель?
> Зыж
> А если и следующую?
> До инкремента?
> Будет увеличивать неинициализированный указатель?Вот... уже начинаем понимать, что такое указатель! :D
Есть переменная - значит есть адрес.Да, нормально инкрементирует его и компылятор должен молчать, а вот на free() ругнётся.
$ scan-build gcc test.c
test.c:10:2: warning: Function call argument is an uninitialized value
free(str_p);
>Вот... уже начинаем понимать, что такое указатель! :D
>Есть переменная - значит есть адресВот не трынди, ок?
Переменная есть переменная. У неё есть свой адрес, а вот что по этому адресу?
Если она не инициализирована, то значение её не определено. Другими словами, там мусор.
В случае компиляции с отладкой, там может быть что-то вменяемое (например "MMM..." для строк например). И на этом многие прокалывались (когда релиз крашился, а дэбаг работал).
>Да, нормально инкрементирует его и компылятор должен молчать, а вот на free() ругнётся.А вот от анализатора как раз хотелось бы большего.
Если разыменовывать неинициализированную, то да мусор. А если использовать операцию взятия адреса, то будет вполне себе валидное значение - адрес.
А если без если, то анализатор должен предупреждать об операциях с переменными с неопределённым значением.
Он ругается на эту строку потому что при следующем упоминании str_port мы затёрли значение, а то которое положили в этой строке ни разу не использовали, но ни как не потому что в этой строке мы затираем значение которое ни разу не использовали (про что вы подумали).
> Он ругается на эту строкуКакая нафиг строка ЭТО УКАЗАТЕЛЬ! НЕТ в С строк.
Я про строки кода, а не про содержимое переменных. Читать научись.
> Какая нафиг строка ЭТО УКАЗАТЕЛЬ! НЕТ в С строк.Есть переменная, которая хранит значение адреса. Это значение перезаписывается без использования первого значения. Первое присваивание можно выбросить без потери внешних эффектов программы. Компилятор справедливо дает понять дебилу-программисту, что вероятно, он делает не то, что думает.
Вот только согласно павлинуху он матюгается именно на первое присваивание, а не на второе (которое может быть хрензнаетгде).
И НЕ матюгается в случае использования НЕинициализированной переменной (выше обсудили).
В общем дэбилом программист будет именно тогда, когда понадеется на этот анализатор, а не на свою голову.
str_port=адрес начала выделенного 5 байтового пространства. Он не должен на это ругаться
Дело даже не в том что это указатель. Переменная может быть смаппирована на порт вывода например. Который может вообще не читаться.
Без volatile это UB, а с volatile он и ругаться не будет.
Позорище-то какое. Павлуша, оказывается, не понимает указатели.>str_port = str_p; // Вот тут оно матерится, что "Value stored to 'str_port' is never read"
>
>str_port = strpbrk(fulladdr, ":");Смотри. В первой строчке кода ты кладёшь некое значение (вообще не важно в данном случае, указатель или просто int) в str_port, дальше это значение не читаешь из этой переменной, а сразу же, во второй строчке, записываешь новое значение в эту же переменную.
Первая строчка вообще бесполезна, и оно на неё ругается. В принципе оно могло бы и на обе строчки указать: здесь мол ты пишешь, а вот здесь опять туда же пишешь. Но решили, видимо, не перегружать сообщениями.
> Позорище-то какое. Павлуша, оказывается, не понимает указатели. ...Наверное просто переменные, к указателям данная ошибка наверное имеет таки косвенное отношение.
> Но решили, видимо, не перегружать сообщениями.
нашего Павлика.
Скорее всего Павлик автоматически в голове разыменовывает указатель и не понимает, что слово Value в сообщении анализатора означает сам указатель, а не строка, на которую он указывает.
> Скорее всего Павлик автоматически в голове разыменовывает указатель и не понимает, что
> слово Value в сообщении анализатора означает сам указатель, а не строка,
> на которую он указывает.Дак естественно, что в контексте указателей анализатор имеет ввиду адрес, к-й этот указатель хранит. Это ж естественно, но Паша что-то не понимает.
Вы правы, добавлю ссылку на "стандарт" http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.14.html
http://tigcc.ticalc.org/doc/string.html#strpbrk"strpbrk returns a pointer to the first occurrence of any of the characters in s2"
>char *str_port;
>char *str_p;
>str_p = (char *) calloc(1, 5);
>str_port = str_p; // Вот тут оно матерится, что "Value stored to 'str_port' is never read"
>str_port = strpbrk(fulladdr, ":");И абсолютно правильно матерится. Не нравится - не заставляй умный анализатор проверять свое творчество.
А вообще лучше блоб нвидевский проверь анализатором и расскажи нам об успехах.
А теперь я покажу, как спрятать от этой дуры "double free"
#include <stdlib.h>
int main(void)
{
char *a;
char *b;
b = (char *)calloc(1, 5);
a = b;
a++;
free(b);
free(a);return 0;
}$ scan-build gcc -Wall -Wextra -W test.c
scan-build: Removing directory '/tmp/scan-build-2014-01-07-43' because it contains no reports. // ДА ТЫ ЧО??!!!!
./a.out
*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x0000000001573010 ***
======= Backtrace: =========
/usr/lib64/tls/x86_64/libc.so.6[0x3000878b66]
./a.out[0x4005c7]
/usr/lib64/tls/x86_64/libc.so.6(__libc_start_main+0xf5)[0x3000821455]
./a.out[0x4004a9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 00:0f 606571 /tmp/a.out
00600000-00601000 r--p 00000000 00:0f 606571 /tmp/a.out
00601000-00602000 rw-p 00001000 00:0f 606571 /tmp/a.out
01573000-01594000 rw-p 00000000 00:00 0 [heap]
...
...
...
А чё у тебя гцц, а не шланг?
Палишься? :D
> А чё у тебя гцц, а не шланг?шлаг это компылятор!
На, скушай
$ clang -W -Wall -Wextra test.c
$ echo $?
0
> Палишься? :DПалишься, сыннко! :D
Я ваще-то про Шланг Static Analyzer
Дык не видно где ты его применяешь.
Да уж. Как говорил Бабаян, указатели - головная боль архитектуры современных компьютеров.
На ассемблере куда проще работать с адресами и указателями и это (факт!). Ждём патч для Си на преобразование указателей в более человеческую форму!11
Ну… пока что(?) лучше с ними, чем без них.
Не, в С++ (особенно начиная с С++11) их применять вообще нет надобности. Но конструкции порой, скажем так, сложные получаются.
Это головная боль Бабаяна, может? ну предельно примитивная же конструкция. Что может быть проще чем коробочка, в которой лежит номер другой коробочки?
Ага, "проще некуда" и прям совсем не заставляют задуматься конструкции типа этой: "(*(void(*)())0x8048330)((char *)10,(int *)0x8048341);" которые довольно-таки часто можно встретить в разных эксплойтах или в сорцах доисторических времен, этак 80х-90 годов, где если не через строчку, в каждом файле можно увидеть подобное:)
пффф...
typedef void (*func_t)();
#define FUNC_ADDR (func_t)0x8048330
#define ARG1 (char *)10
#define ARG2 (int *)0x8048341int main(void)
{
func_t func = FUNC_ADDR;func(ARG1, ARG2);
return 0;
}и что тут сложного?
Единственное, что там вообще может заставить задуматься, это первая звёздочка, которая там на самом деле и не нужна вовсе. Тут расписано:
http://stackoverflow.com/a/17321313Единственное, что делает ту запись сложной, это намеренная обфускация кода. Ну так это в любом языке можно сделать, даже без указателей.
Никто не говорил, что это сложно. Ваша конструкция вообще читается с первого раза). Это заставляет задуматься и какое-то время потратить на разбор.
заставляет, но я просто к тому, что не стоит выдавать обфусцированный код за проблемы указателе
Заставляет. Я имею ввиду, что не стоит выдавать обфусцированный код за проблемы указателей или проблемы Си (см. начало обсуждения). Можно писать и с использованием указателей так, что сразу всё будет понятно. И Си дает достаточно возможностей для написания выразительного кода. Просто в том примере код намеренно запутан.
Приведённый пример прост, вызов функции с параметрами указателями на char с значениями 10, и 0x804834, по указателю с значением 0x8048330 который есть указатель на функцию, принимающую и возвращающую void, есть гораздо сложнее.
Пупок не развяжется ещё "сложнее" разбирать ? Линки на иоцц с сложными, добавлю себе в портфолио)
> принимающую и возвращающую voidЕсли бы она принимала void, то как ей аж 2 параметра передали? В чистом Си (в отличии от C++) запись "void fun()" означает функцию, которая принимает неограниченное количество аргументов любых типов. Это оставлено для совместимости со старым кодом. Вот тут подробнее:
[1] http://stackoverflow.com/questions/51032/is-there-a-differen...
[2] http://stackoverflow.com/questions/13319492/understanding-th...
Ну дык кто его знает каким компилятором думается компилить C или С++,
поэтому написал бы "(*(void(*)(char*,int*))0x8048330)((char *)10,(int *)0x8048341);"
Вопрос корректности записи оставался на совести автора, наше дело представить
её смысл.
> Ну дык кто его знает каким компилятором думается компилить C или С++Естественно C. Потому что на C++ приведенный пример не скомпилируется, т.к. в C++ func() означает что функции не передаются аргументы. Более того, про C++ никто и не заикался, было явно написано про Си.
> поэтому написал бы "(*(void(*)(char*,int*))0x8048330)((char *)10,(int *)0x8048341);"И получил бы на выходе совсем другой бинарь, вероятно с неработающим эксплоитом. Вот вывод diff от бинаря по оригинальному коду к бинарю с вашим кодом:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
- xorl %eax, %eax
+ movl $134513456, %eax
movl $134513473, %esi
movl $10, %edi
- movl $134513456, %edx
- call *%rdx
+ call *%rax
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
> Вопрос корректности записи оставался на совести автора, наше дело представить
> её смысл.Вы потеряли смысл записи что в случае с приведением к функции принимающей void, что в случае с приведением к (char *, int *). Так как в обоих случаях эксплоит работать не будет.
>[оверквотинг удален]
> - movl $134513456,
> Мx
> - call *%rdx
> + call *%rax
> xorl
> Йx, Йx
> addq
> $8, %rsp
> .cfi_def_cfa_offset 8
>
В оригинале
movl $134513456, Мx
call *%rdx
с аргументами:
movl $134513473, %esi
movl $10, Мi
не оригинал:
movl $134513456, Йx
call *%rax
с аргументами
movl $134513473, %esi
movl $10, Мi
всё то же самое, немного перевёрнутое компилятором, у них свои тараканы.
Так же разные бинари получите компиля разными компиляторами.
То, что удалилось очищение %eax вряд ли повлияет на работу эксплойта.
Забыл про разметку.
В оригинале
movl $134513456, %eaxcall *%rdx
с аргументами:
movl $134513473, %esimovl $10, %di
не оригинал:
movl $134513456, %eaxcall *%rax
с аргументами
movl $134513473, %esi
movl $10, %edi
всё то же самое, немного перевёрнутое компилятором, у них свои тараканы.Так же разные бинари получите компиля разными компиляторами, и на разных ОС.
То, что удалилось очищение Йx вряд ли повлияет на работу эксплойта.
В таком случае действительно лучше приводить к void (*func_t)(char *, int *). Просто нужно быть уверенным на 100%, что эксплоит будет работать после этого. А для этого нужно иметь возможность его протестировать после изменений. Это то, почему я изначально решил оставить приведение "как есть". А так да, намного красивее, когда аргументы явно указаны.
Я тут ненароком подслушал ваши дебаты,но у меня один вопрос - почему в x86_64 принято передавать аргументы через регистры, а не через стек ? На x86, к примеру, все эти инструкции выглядели бы так:
sub esp, 8
mov dword[esp+4],0x8048341
mov dword[esp],10
mov eax,0x8048330
call eax
add esp, 8
Конечно я понимаю, что обращение к регистрам намного быстрей, чем к ОЗУ, но как вопрос, мне это интересно.
Так в GNU/Linux. В *BSD, solaris передаются через стек. В других не знаю.
> Так в GNU/Linux. В *BSD, solaris передаются через стек. В других не
> знаю.не порите чушь, ей больно
Чтобы быстрее вызывалось.
Поиск по запросу "amd64 abi parameter passing":[1] http://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_...
[2] http://stackoverflow.com/questions/17437191/function-paramet...
[3] www.x86-64.org/documentation/abi.pdf
Может быть. *BSD ковырял последний раз ещё на x86, а solaris на x86_64-32 разрадная
полностью, по крайней мере те проги, что компилятся в ней c gcc.
> Да уж. Как говорил Бабаян, указатели - головная боль архитектуры современных компьютеров.Твой Бабаян - обычный неосилятор указателей !!!
:-)))
>> Да уж. Как говорил Бабаян, указатели - головная боль архитектуры современных компьютеров.
> Твой Бабаян - обычный неосилятор указателей !!!
> :-)))И - да, он авторитетище!
Странно, у меня всё ок. Проверяю ваш код вот так:
$ scan-build gcc -c main.cscan-build: Using '/usr/bin/clang' for static analysis
main.c:10:9: warning: Attempt to free released memory
free(a);
^~~~~~~
1 warning generated.
scan-build: 1 bugs found.
scan-build: Run 'scan-view /tmp/scan-build-2014-01-07-011258-4567-1' to examine bug reports.
Версия clang:
$ aptitude -F %p search ~i^clang
clang-3.4
> А теперь я покажу, как спрятать от этой дуры "double free"Лол, теперь ты обиделся на статический анализатор за то что он обнаруживает НЕ ВСЕ твои косяки? Это не удивительно, особенно если учесть что ты не умеешь его использовать.
>> А теперь я покажу, как спрятать от этой дуры "double free"
> Лол, теперь ты обиделся на статический анализатор за то что он обнаруживает
> НЕ ВСЕ твои косяки? Это не удивительно, особенно если учесть что
> ты не умеешь его использовать.ТЫ МУДИЛО АНОНИМНОЕ, ВЫСЕР ВАКУУМ ЭТО ВАЖНАЯ ИНФОРМАЦИЯ
ути-пути, какие мы нежные. опять двойку в школе получил?
А в нем таки есть поддержка OpenMP или нет?
есть поддержка OpenMP 3.1, сейчас активно пилится 4.0
О, попробую снова собрать свою генточку сабжем. На 3.3 почти удалось.
> О, попробую снова собрать свою генточку сабжем. На 3.3 почти удалось.А помните как линуксоеды тут и на лоре на фряшников собачилисть?
А терерб - наперегонки :)
Верь в это.
Наперегонки что? Эксперементируют со своей системой?
На так у меня (на десктопе, не на серверах) половину пакетов интеловским компилятором собрано.
Вот только в линухе эти эксперементы по желанию, а в бсде добровольно-принудительно.
И уж тем более я не агитирую за самый кошерный компилятор, как некоторые. Просто гцц самый надёжный вариант во всех смыслах.
Вот да, согласен.У меня мотивом попыток собрать генту шлангом выступила быстрая сборка. На Firefox, например, разница была в 10 минут (емнип) в пользу clang. Однако далеко не все пакеты собираются цлангом, а некоторые даже если и собираются - работают весьма странно, пример - падающий компиз при попытке свернуть окно в заголовок.
На FreeBSD шлангом собираются уже почти все порты. Gentoo просто тормозит с импортом соответствующих патчей.
Или порты FreeBSD отстают по разнообразию от гентушного дерева.
over-24K портов FreeBSD отстают от портов Gentoo по разнообазию версий разве что, но не по уникальности.
А в портах есть ядро Linux? :D
Таки есть :) Правда не самый свежак :)
Не в портах, но лежит прямо рядышком с ядром фряхи в виде модулей ядра фряхи, версии 2.6.16% ls -ahl /boot/kernel|grep linux
-r-xr-xr-x 1 root wheel 12K 31 дек 23:20 amr_linux.ko
-r-xr-xr-x 1 root wheel 57K 31 дек 23:20 amr_linux.ko.symbols
-r-xr-xr-x 1 root wheel 44K 31 дек 23:20 geom_linux_lvm.ko
-r-xr-xr-x 1 root wheel 110K 31 дек 23:20 geom_linux_lvm.ko.symbols
-r-xr-xr-x 1 root wheel 12K 31 дек 23:20 ipmi_linux.ko
-r-xr-xr-x 1 root wheel 57K 31 дек 23:20 ipmi_linux.ko.symbols
-r-xr-xr-x 1 root wheel 681K 31 дек 23:20 linux.ko
-r-xr-xr-x 1 root wheel 2,5M 31 дек 23:20 linux.ko.symbols
-r-xr-xr-x 1 root wheel 14K 31 дек 23:20 mfi_linux.ko
-r-xr-xr-x 1 root wheel 64K 31 дек 23:20 mfi_linux.ko.symbols
-r-xr-xr-x 1 root wheel 94K 31 дек 23:20 systrace_linux32.ko
-r-xr-xr-x 1 root wheel 261K 31 дек 23:20 systrace_linux32.ko.symbolsМожно распаковать gentoo-stage3 в chroot и компилять под линукс использую portage
> Можно распаковать gentoo-stage3 в chroot и компилять под линукс использую portageЗачем распаковывать вручную? Есть порты gentoo: http://www.freshports.org/search.php?query=gentoo
Происходит ли какая активность в freebsd по проектам, финансируемым DARPA по поводу
автоматизации управления сетевым траффиком? Если в теме. Интересно.
> Происходит ли какая активность в freebsd по проектам, финансируемым DARPA по поводу
> автоматизации управления сетевым траффиком? Если в теме. Интересно.В списке спонсоров гос учреждений нет. В OpenBSD после того как Тео послал их в пешее гомко и открыто - тоже.
В линксе всё Ок, вся братва присутствует :)
Если интересно, то делал вот так http://www.gentoo-wiki.info/HOWTO_ICC_and_Portage с небольшими изменениями).
Вот это тоже http://habrahabr.ru/post/83324/ читал, но делал по первой ссылке.
Не вижу особых трудностей сделать также по аналогии для clang.
В любом случае удобно получается.
Но честно говоря результат больше джаст4фан, чем реальный профит.
Будущее за LLVM, я это давно уже понял.
И промежуточный байткод - это круто, так как можно компилировать в него программы, выполняя супероптимизацию и в таком виде можно распространять их, а конечную компиляцию в машинный код выполнять в момент установки под нужную архитектуру. Эта компиляция по-идее должна осуществляться намного быстрее, чем из исходников, написанных, например, на Си.В .NET круто, что там общий набор библиотек и из любого языка можно использовать одни и те же функции. Я не понял пока, тут так же будет или нет ?
> Будущее за LLVM, я это давно уже понял.
> И промежуточный байткод - это круто, так как можно компилировать в него
> программы, выполняя супероптимизацию и в таком виде можно распространять их, а
> конечную компиляцию в машинный код выполнять в момент установки под нужную
> архитектуру. Эта компиляция по-идее должна осуществляться намного быстрее, чем из исходников,
> написанных, например, на Си.Юзвери лают – караван идет.
> В .NET круто, что там общий набор библиотек и из любого языка
> можно использовать одни и те же функции. Я не понял пока,
> тут так же будет или нет ?Если MS заинтересуют они будут пилить в гордном одиночистве, ибо винда в транке llvm ни кому не нужна
> Юзвери лают – караван идет.Вы хоть знаете, что такое LLVM и как она работает ?
> Если MS заинтересуют они будут пилить в гордном одиночистве, ибо винда в транке llvm ни кому не нужна
Причём тут MS ?
Никто вроде про винду и не вспоминал.Про ихнюю .NET я вспомнил только потому, что какой бы язык в ней вы не использовали, базовый набор библиотек в нём один и тот же. Т.е. будь это C#, F# или Pyton например они могут использовать набор функций фреймворка. И поэтому нет необходимости при изучении нового языка изучать и его библиотеки.
В результате базовый набор ограничений тоже оказывается для всех одним и тем же. В общем, минусы тоже есть, хотя плюсы велики, да. Под никсами, впрочем, сишный аби обычно вполне достаточен.
Хомячкам из норки не видно каким убожеством является их божество .NET,
потому-что ничего больше не знают, а знали бы, даже не упоминали бы
его, не говоря о выражении мнения о каком-то его удобстве и превосходстве.
А не развернете ли вы свое виденье на платформу .Net?
> Хомячкам из норки не видно каким убожеством является их божество .NET,
> потому-что ничего больше не знают, а знали бы, даже не упоминали бы
> его, не говоря о выражении мнения о каком-то его удобстве и превосходстве.Безразницы, кто написал .NET и то, что её больше используют под виндовс.
.NET - это прежде всего одна из технологий прогресса и очень даже неплохая.Разработчики, делающие LLVM это прекрасно понимают и берут из неё лучшее и то, что они сделали, получается намного лучше .NET.
И вообще надо внимательней читать, прежде чем чушь всякую писать, а то увидел тут одно знакомое слово .NET и сразу написал всю чушь, которая возникла в голове.
У LLVM оптимизатор не зависит от языка, т.е. если сейчас считается С/С++ одним из самых быстрых языков, благодаря своему оптимизатору, то в LLVM теоретически программа написанная на любом языке будет работать одинаково быстро, при условии, что сами алгоритмы на этих языках будут совпадать.
И так же хотелось бы, чтоб можно было без труда использовать в любом из языков любую внешнюю функцию, написанную тоже на любом языке, как в .NET можно написать функцию на C# и использовать её в F#. Или если написан, какой-нибудь фреймворк, то его функции будут доступны в любом языке .NET. Можете ли вы например начать быстро использовать функции из библиотеки QT в любом другом языке, кроме С/С++ ? Врядли, скорее всего вам перед этим придётся попотеть, чтобы что-то настроить. Под .NET фреймворк пишется один раз и сразу доступен из всех .NET языков. Если же брать обычные(не .NET) языки, то для каждого из них надо писать дополнительные прослойки, чтобы они могли начать использовать библиотеки фреймворка.
Вот именно такое хотелось бы иметь и в LLVM. Хотелось бы, чтобы фреймворк QT был доступен любому LLVM языку и при этом он был равен для всех языков по функциональности и не надо было бы писать всякие дополнительные прослойки по поддержке фреймворка.
Как Вас колбасит от проблемы разного названия функций в разных библах. По
мне так reference в зубы и вперёд.
Не спасёт Вас LLVM потому-что в мире опенсурса тут же начнут появляться
альтернативы, форки и т.д. Это как ситуация с C++ STL и boost-
всё, что есть в STL продублировали в boost, и обязательно с некоторыми труднозапоминаемыми изменениями
в семантике и сигнатурах. Обязательно, стань LLVM стандартом, начнут появляться разные
LLVM++ и всюду начнут пропихиваться, потому-что это верный способ для
программеров показать свою деятельность и выделить именно свой проект.
Сомниваюсь, что форк LLVM появится, но если появится, то ничего страшного.> Это как ситуация с C++ STL и boost-
> всё, что есть в STL продублировали в boost, и обязательно с некоторыми > > > > труднозапоминаемыми изменениями
> в семантике и сигнатурах.Пусть дублируют, форкают и т.д. сколько хотят. Мне главное, чтобы на моём любимом языке это всё было сразу доступно. И что б мне не приходилось самому приспосабливать новые фреймворки под свой язык, а потом их новые версии и т.д.
Именно в .NET эта проблема решена.
Я упоминаю .NET только потому, что не знаю какой ещё пример привести, возможно существуют ещё примеры, но я не в курсе.> По мне так reference в зубы и вперёд.
Если у вас так много времени, то пожалуйста, я лишь хочу, чтобы не приходилось по много раз повторять одинаковые действия.
Вот скажите, что плохого в том, что один фреймворк будет доступен на всех языках программирования ? А не для каждого языка свой. Пусть лучше уж будет куча фремворков, но доступных на всех языках и пусть каждый выберит для себя лучший. Это же можно реализовать, так почему бы это не сделать ?
> Сомниваюсь, что форк LLVM появится, но если появится, то ничего страшного.Не появится по одной простой причине - developers, developers, developers (c) Ballmer
Не найдется столько разработчиков компиляторов, чтобы его тянуть.
Сказочник тот ещё) никогда не видел, чтобы у кого-то возникали трудности вызова функции из данимаческой библиотеки, в чем проблема - таблицу символов забыли сделать или сошник с dll шкой перепутали ?
.NET -это прежде всего проприентарный продукт, который создали микрософтеры для своей Windows и они явно не хотели, чтобы его юзали под сторонними платформами, раз не открыли для этого его исходники или же не сделали отдельные бинарные реализации под каждую платформу, как это сделали оракли я джавой. И вообще, с момента появления этой "вм" для шарпа, не недолюбливаю его за его тормознутость. Каждая программа на шиндошс, написанная на C#, у меня или запускается по пол минуты или тормозит в ходе работе.. Хорошо, что с Mono ситуация по-лучше, но и она далека от уровня компилированных программ.
.NET создали, как конкурента Яве, но Макрософт реализовала его только под виндовс и понятно почему. При этом стандарт открыт, а реализация функций закрыта, но иногда Майкрософт выкладывает куски.И что вы все привязались к этому .NET`у. Вы не можете уловить суть вопроса, который я задал ?
Все современные среды разработки поддерживают автодополнение. При вводе точки появляется список функций и переменных объекта. Если написать новый фреймворк под .NET, то он станет доступным под любым .NET языком и в среде разработки будут работать автодополнение и т.д. При этом программисту не надо производить никаких лишних действий.
> Сказочник тот ещё) никогда не видел, чтобы у кого-то возникали трудности вызова функции из данимаческой библиотеки, в чем проблема - таблицу символов забыли сделать или сошник с dll шкой перепутали ?
Речь не о трудностях, а о том, что это надо делать самому, когда это уже можно было бы и не делать. - Поставил новую библиотеку, она зарегистрировалась в системе и сразу же стала доступна(видна) во всех установленных языках. Используешь из неё объект, жмёшь точку и появляется список его методов и т.д.
У меня тоже никогда не возникало проблем с программированием на ассемблере, но, понимаете, это не удобно и отнимает много времени ?
Вам видимо прогресс не нужен, пусть всё остаётся, как есть ?
Зачем придумали стандарт С++11, если я и на обычном С++ неплохо программирую ?
Зачем эти классы нужны, если я могу всё функциями и процедурами сделать ?
Зачем нужна среда разработки, если я и в блокноте умею программировать ?
На хрен вообще DE придумали, если я могу в консоли работать ?
>.NET - это прежде всего одна из технологий прогрессаПопахивает матёрым маркетинговым булшитом и промытыми мозгами.
>Разработчики, делающие LLVM это прекрасно понимают и берут из неё лучшее и то, что они сделали, получается намного лучше .NET.Ничего они оттуда не берут. НИЧЕГО. Запомните это хорошенько.
Зыж
На заметку — gcc тоже транслирует в бит-код. При этом язык — это фронэнд, целевая платформа — бэкэнд. А вы что думали, как он ещё так быстро и столько платформ умеет? МакОСь Х на нём для двух платформ выпустили, первые айфоны, андроиды, итд, итп. С отставанием в 2-3 года мс выпустили нечто подобное для армов.
Это же касается и оптимизаторов. Большинство современных методов оптимизации появились именно там (тотже lto из сабжа). И всего того, что вы там понаписали. Всё это технологии ещё прошлого века. Так что разберитесь в своих знаниях, потом начнёте проповедовать.
Коротко — Llvm интересен не этим. Дотнет не интересен вообще.
ззыж
Чтобы не быть голословным, пруфы:
1. http://en.wikipedia.org/wiki/Register_transfer_language
>register transfer language (RTL) is a kind of intermediate representation (IR) that is very close to assembly language, such as that which is used in a compiler. It is basically an operation which is used to transfer information from one place to another.IR — ничего не напоминает?
2. http://ru.wikipedia.org/wiki/GNU_Compiler_Collection#.D0.A1....
>Все компиляторы имеют общую внутреннюю структуру: front end, который производит синтаксический разбор и порождает абстрактное синтаксическое дерево, и back end, который конвертирует дерево в Register Transfer Language (RTL), выполняет различные оптимизации, затем порождает программу на языке ассемблера, используя архитектурно-зависимое сопоставление с образцом.выполняет различные оптимизации(!!!). НЕЗАВИСИМО от языка (front end'а)
3. www.opennet.ru/opennews/art.shtml?num=38576
>Для набора компиляторов GCC разработан новый фронтэнд gccrs, позволяющий компилировать программы, написанные на языке Rust.
>>So to learn the language i've been writing this front-end to GCC. Only really a a month or so on and off work in between work.В одно рыло, по вечерам и джаст4фан, фронт-энд для языка (и это не бэйсик :D) подготовлен в районе месяца.
> Ничего они оттуда не берут. НИЧЕГО. Запомните это хорошенько.Я и не говорю, что берут, но LLVM начали делать позднее .NET и его разработчики учли опыт и .NET и виртуальной машины Java и обычных компиляторов, поразмыслили и выбрали лучшее решение в данной области.
> На заметку — gcc тоже транслирует в бит-код.
Любой компилятор сначала делает биткод, а потом его оптимизирует, т.к. этот способ намного быстрее, чем производить оптимизацию оперируя переменными самого языка.
То, что GCC крутой компилятор и многое умеет, с этим никто и не спорит, но почитайте про отличия GCC и LLVM и поймёте, чем последний лучше. И компилятор GCC очень сложно приспособить для компиляции кода, написанного на другом языке, не С/С++.
Да и дело не в том, что GCC транслирует в байткод, а в том, что в самом байткоде идут ссылки на исходный код. Сам байткод не является полноценным и независимым и он только для одного языка. В LLVM байткод - это полноценная самодостаточная виртуальная машина с бесконечным числом регистров и любой её байткод можно прочитать на её собственном ассемблере, при этом исходники абсолютно не нужны.
В GCC вся оптимизация завязана на код. В LLVM любая часть оптимизации - это отдельная функция, которая называется фазой. Любые комбинации функций можно включать в процесс оптимизации и также можно легко добавлять свои при этом не вникая в работу всего компилятора.
В LLVM архитектура описывается в отдельных файлах и также не завязана на код, можно добавить любой новый процессор с совершенно новой, до этого неизвестной архитектурой, просто написав соответствующие файлы с описанием команд. Если файлов недостаточно, то также можно написать свои фазы компиляции под архитектуру, при этом опять же не вникая в алгоритм работы самого компилятора.
В LLVM написать свой язык намного проще. Просто делаешь компилятор в байткод LLVM и ваш язык сразу же поддерживает крутую оптимизацию, как и у С/С++ и многоплатформенность. Вам не надо заботится ни об алгоритмах оптимизации, ни об генераторах машинного кода под все архитектуры, это всё сделает LLVM.
> И всего того, что вы там понаписали. Всё это технологии ещё прошлого века.
Не важно в каком веке разработаны эти технологии, а важно то, удобно ли ими пользоваться сейчас ?
LLVM и создаёт это удобство, он наводит порядок в коде, она разбивает код на отдельные модули, которые несут свои функции, которые можно развивать независимо друг от-друга. Вот скажите, зачем каждому программисту, реализующему свой язык программирования писать заново для него оптимизацию и генераторы кода под все архитектуры ? Не лучше ли объединиться и вместе разрабатывать один оптимизатор, но супермощный и для всех ? Не лучше ли написать один раз генераторы машинного кода под платформы и потом их использовать во всех языках ? Или вы считаете, что это хорошо тратить лишнее время на реализацию в каждом языке алгоритмов оптимизации и генерации машинного кода ?GCC крут, но не настолько маштабируем, как LLVM и LLVM - это растущая замена ему.
>Сам байткод не является полноценным и независимым и он только для одного языка. В LLVM байткод - это полноценная самодостаточная виртуальная машинаТак, свободны молодой человек. :D
Полный бред несёте. Очевидно, что вы были (надеюсь, что были), мягко говоря, не в курсе.
И теперь просто не желаете признавать свои ошибки. В силу воспитания и юношеского максимализма.
man intermediate representation (IR) (хотя, впрочем, предвидя это, пруфы я выше уже дал http://www.opennet.me/openforum/vsluhforumID3/93448.html#146 которые вы не успели прочитать и сразу ринулись в «бой» :D)Ещё раз. LLVM интересен не по-этому. Разберитесь с этой аббревиатурой. Как впрочем и с gcc.
> Полный бред несёте. Очевидно, что вы были (надеюсь, что были), мягко говоря, не в курсе.И теперь просто не желаете признавать свои ошибки
Нет, я просто был не в курсе или просто подзабыл.
А недостатки GCC описаны тут http://rus-linux.net/MyLDP/BOOKS/Architecture-Open-Source-Ap...
Возможно в GCC какие-то уже устранили, он же развивается, но я не в курсе.
Ну а ваш предыдущий комментарий, похоже был позже моего написан, конечно бы я его учёл, если б увидел.
>Ну а ваш предыдущий комментарий, похоже был позже моего написанТам время указано если что.
зыж
llvm хорош тем, что он именно llvm (Low Level Virtual Machine), а не компилятор.
Впрочем, у gcc тоже уже имеются подобные vm с jit'ами и пр.Поэтому ваш "энтузиазм" по-поводу дотнета (а зачем он вообще, если код ВСЕГДА выполняется на одной и той же платформе?) и использование сабжа только лишь для статической компиляции, мягко говоря, не обоснован.
Впрочем, пока что и llvm не доказал, что это не ещё одна тормозная «жаба». Как пример, ситуация с шеэдерами в открытых дровах r600 и когда студент реализовал свой, более производительный компилятор шэйдэров.
Но для проектов типа PNaCl (Portable Native Client) безусловно интересно.
Как и вообще чисто академически.
И по поводу LLVM я не знаю, что выйдет из него, но после понятия основных механизмов его функционирования, я думаю, что у него большое будущее.Похоже вы думаете, что LLVM - это только виртуальная машина с JIT компиляцией, но это не так.
Что LLVM не компилятор - это я знаю, но компилятор тоже входит в его состав.
LLVM - не будет "ещё одной тормознутой жабой" никогда, т.к. он содержит полноценный компилятор, вы сами можете выбрать какой код скомпилировать - байткод или нативный. Последний будет почти такой же, как и у GCC(+-) по производительности и от "тормознутой жабы" он уже очень далеко.По поводу же сравнения GCC и LLVM, то в LLVM начали с чистого листа и реализуют, как всё и было задумано. GCC же постоянно надо переделывать в другую сторону, отдаляясь от того, что есть. Поэтому путь GCC сложнее и я не знаю, на каком он сейчас этапе. Выше я приводил вам ссылку на статью и там много недостатков было, но статья довольно старая уже.
И мне по большому счёту всё равно GCC или LLVM, но если уж GCC, то пусть в нём появится всё то, что я увидел в LLVM.
И у меня нет энтузиазма по поводу дотнета, т.к. я им не пользуюсь. Вы все похоже вообще не понимаете моего вопроса. Я уже устал каждому его переписывать по 100 раз.
Единственное почему я его вспомнил - это общие библиотеки между языками, чтобы можно было установить фреймворк и сразу же полноценно им пользоваться в любом языке, установленном на компьютере. Сейчас нельзя установить QT и пользоваться сразу же её библиотеками, например, в Хаскелле. Если нужно использовать в Хаскелле QT, то необходим специальный пакет для данного языка. Тоже самое касается абсолютно всех языков(наверно). В НЕТе же все библиотеки между языками общие потому, что там есть стандарт по которому внутри все языки одинаковые и связь между ними одинаковая, а для нас внешне они отличаются синтаксисом и т.д.
Вот я и хотел, чтобы в LLVM было тоже самое и теоретически это можно реализовать, ведь там между всеми языками будет нечто общее. А промежуточный байткод - это и есть возможная связь. И кстати этот промежуточный байткод вполне можно компилировать в нативный код, который потом будет работать без JIT, а как обычный код после компилятора.Видите, нет никакого энтузиазма по поводу НЕТ, я просто вижу в нём неплохую фичу, которую надо заимствовать в других технологиях.
>И по поводу LLVM я не знаю, что выйдет из него, но после понятия основных механизмов его функционирования, я думаю, что у него большое будущее.Безусловно.
Просто мне порой смешно смотреть, когда начинаются «войны» компилятора gcc с llvm.
Это вообще разное ПО.зыж
И вообще, не вижу причин, почему бы в gcc не сделать какой-нибудь бэкэнд для компиляции в бит-код llvm. :D
По всем остальным моментам мне проходить по второму кругу уже не интересно, сори.
Итак чуть ли не в каждой теме ссылки на RTL вставляю — народ вообще не понимает о чём пытается спорить.
>[оверквотинг удален]
> Просто мне порой смешно смотреть, когда начинаются «войны» компилятора gcc с
> llvm.
> Это вообще разное ПО.
> зыж
> И вообще, не вижу причин, почему бы в gcc не сделать какой-нибудь
> бэкэнд для компиляции в бит-код llvm. :D
> По всем остальным моментам мне проходить по второму кругу уже не интересно,
> сори.
> Итак чуть ли не в каждой теме ссылки на RTL вставляю —
> народ вообще не понимает о чём пытается спорить."GCC поддерживает множество систем предварительной обработки кода и разрабатывается активным и многочисленным сообществом. В течение длительного промежутка времени GCC был компилятором языка C с поддержкой различных целевых архитектур и с наличием поддержки нескольких дополнительных языков программирования, реализованной с использованием сложных приемов. По прошествии лет сообщество разработчиков GCC медленно реализовывало более совершенную архитектуру. В версии GCC 4.4 используется отдельное представление кода оптимизатором (известное как "Кортежи GIMPLE" - "GIMPLE Tuples"), которое в большей степени отделено от представления системы предварительной обработки кода, чем использующееся ранее. Также существуют системы предварительной обработки кода для языков Fortran и Ada, использующие необработанные деревья стандартного синтаксического анализа (AST).
Хотя эти продукты и были успешны, возможности их использования жестко ограничены, так как они проектировались как монолитные приложения. В качестве примера можно упомянуть о том, что компилятор GCC невозможно встроить в другие приложения, его невозможно использовать в качестве JIT-компилятора или интрепретатора, а также невозможно выделить и повторно использовать отдельные части GCC без задействования всего компилятора. Разработчикам, желающим использовать систему предварительной обработки кода для языка C++ из GCC в качестве инструмента для генерации документации, индексации кода, рефакторинга и статического анализа приходилось использовать GCC как монолитное приложение, выводящее интересующую их информацию в формате XML или разрабатывать расширения для использования стороннего кода в GCC.
Существует множество причин по которым отдельные части GCC не могут использоваться повторно в качестве библиотек, включающее в себя такие причины, как чрезмерное использование глобальных переменных, недостаточное использование инвариантов, некачественно проработанные структуры данных, распределенная кодовая база и использование макросов, которые затрудняют компиляцию кода для поддержки более чем одной комбинации из системы предварительной обработки кода и системы генерации кода. Наиболее сложные для исправления проблемы являются следствием недоработок в первоначальной архитектуре и возраста компилятора. В особенности GCC страдает от недоработок в распределении уровней и создании абстракций: система генерации кода получает доступ к дереву стандартного синтаксического анализа системы предварительной обработки кода для генерации отладочной информации, система предварительной обработки кода генерирует структуры данных для системы генерации кода и весь компилятор зависит от глобальных структур данных, изменяемых с помощью интерфейса командной строки."
Полный текст тут: http://rus-linux.net/MyLDP/BOOKS/Architecture-Open-Source-Ap...
Не знаю, как в новых версиях GCC, может что-то и изменилось. Но представьте сколько им надо внести изменений, не легче ли разработать архитектуру с нуля ?
Вот LLVM это как раз и есть то, что пишется с нуля.И я не спорю о том, что круче LLVM или GCC. Компиляторы GCC считаю одними из лучших. Но если они справятся со всеми проблемами, что написаны выше, то будет хорошо. И не только в байткоде дело, там и других проблем хватает(хватало?).
Ещё раз — llvm не компилятор.
> В НЕТе же все библиотеки между языками общие потому, что там есть стандарт по которому внутри все языки одинаковые и связь между ними одинаковаяАга, счас... Связь с нативными языками есть только если interop уже кто-то прописал правильно. До сих пор помню, как мне как-то нужно было DX использовать из C#, так пришлось все с помощью гугла и поллитры самому прописывать каждую функцию, как параметры передаются и т.д., ну и SlimDX вроде частично помог, хотя там не всё.
>> В НЕТе же все библиотеки между языками общие потому, что там есть стандарт по которому внутри все языки одинаковые и связь между ними одинаковая
> Ага, счас... Связь с нативными языками есть только если interop уже кто-то
> прописал правильно. До сих пор помню, как мне как-то нужно было
> DX использовать из C#, так пришлось все с помощью гугла и
> поллитры самому прописывать каждую функцию, как параметры передаются и т.д., ну
> и SlimDX вроде частично помог, хотя там не всё.Я не имею ввиду нативные языки, а только НЕТовские.
Это и понятно, что у нативных другое устройство и они не приспособлены.И когда упоминаю об желании иметь аналогичную возможность в LLVM, то имею ввиду связь только между языками, использующими LLVM.
> И когда упоминаю об желании иметь аналогичную возможность в LLVM, то имею ввиду связь только между языками, использующими LLVM.То есть в первую очередь шланг и c/c++ - вполне нативные языки. Ты просто не понимаешь о чем говоришь. LLVM очень далек от .net, практически ничего общего, кроме того, что поддерживает jit-компиляцию, но это не главное достоинство llvm.
Скорее всего просто не заметил ваш комментарий.
>т.е. если сейчас считается С/С++ одним из самых быстрых языков, благодаря своему оптимизаторуА ЭТОМУ где вас научили?
С/С++ быстры, потому что ГОРАЗДО ближе к низко-уровнему языку — ассемблеру.
Чтобы понятней — конструкции С/С++ преобразуются в гораздо меньший по объёму машинный код, чем большинство остальных высоко-уровневых языков. И это только для компилируемых языков!!!
И второй плюс — программист на С/С++ гораздо в большей степени владеет информацией в какой именно машинный код трансформируется та или иная конструкция.>И так же хотелось бы, чтоб можно было без труда использовать в любом из языков любую внешнюю функцию, написанную тоже на любом языке, как в .NET можно написать функцию на C# и использовать её в F#.
То, что вас «научили» из любого языка относительно легко создавать и вызывать COM-объекты, ещё не значит, что все остальные языки разучились создавать и вызывать библиотеки (.a, .so,…)
Или вы о том, что там всё однообразно, хоть и безобразно, вызывается (другими одна на всё библиотека классов)? :D
> То, что вас «научили» из любого языка относительно легко создавать и вызывать COM-объекты, ещё не значит, что все остальные языки разучились создавать и вызывать библиотеки (.a, .so,…)Нет, просто хотелось бы, чтобы установил например QT и его функции можно было вызывать в любых других языках. Сейчас надо самому описание внешних функций делать. Если это унифицировать и сделать регистрацию установленных компонентов, то ничего делать самому не надо будет.
Приведу пример: Я хочу установить QT, после чего сразу же в Си заработает следующий код:
#include <QApplication> ...
И я так же хочу, чтобы сразу же заработал следующий код на питоне:
import QApplication ...
И аналогичный код на других языках.
Но такого не будет, потому что для питона, например, надо установить PyQT(или что-то подобное, не помню уже), что является прослойкой(если не ошибаюсь), связывающей данный язык с библиотеками QT.Не будет работать сразу потому, что нет стандарта и нет связи между разными языками и LLVM могла бы обеспечить такой стандарт и такую связь.
Приведу другой пример: Допустим я установил под .NET фреймворк OpenTK. То тогда я могу вызывать функции данного фреймворка, как из С++, С#, F#, Python и любого другого .NET языка.
COM-объект - это совсем другое, не то об чём я.
И кстати мне интересно, какая в Линуксе технология, заменяющая COM ?
>Нет, просто хотелось бы, чтобы установил например QT и его функции можно было вызывать в любых других языках.Для этого есть биндинги (т.е. поддержка в самих языках). Например для Qt:
$ eix qt|grep -i bindi
* dev-libs/libindicate-qt
Description: Python bindings for the Qt toolkit
Description: A python binding for libpoppler-qt4
Description: Ruby bindings for Qt4
Description: Qt Perl bindings
Description: Qt Ruby bindings
…
И то, это для C++-библиотек (там имена в объектниках «коверкаются». подробности http://en.wikipedia.org/wiki/Name_mangling)
Для библиотек С (или при использовании extern "C" в С++, что требуется для dll в винде) всё ГОРАЗДО проще.
А вообще, это не технический, а административный вопрос стандартизации юзер-спейсного АПИ. И всё. Конечно, строем ходить проще, никаких проблем с пробками и транспортными коллапсами.
Но свобода творчества мне лично дороже. :D
Спасибо за разъяснение, но вот по-моему эти биндинги ни к чему, я как раз за построение общего универсального АПИ между языками. Мы же можем из любого языка вызвать Си функцию, но для этого её надо объявить определённым способом (extern(C) или что-то подобное) и надо указать, где находится библиотека и т.д.А можно сделать и по-другому, если все установленные библиотеки будут регистрироваться, где-нибудь, а все языки будут видеть это дерево библиотек и сами с вызываемыми функциями связываться правильно, чтобы программист не делал лишних действий.(это просто пример, возможно не правильный)
А в LLVM такую связь теоретически можно сделать через байткод. Да и при написании нового языка там используются специальные функции LLVM для облегчения написания последнего(конечно можно и без них обойтись и написать всё полностью вручную). Вполне можно добавить в LLVM например функцию, которая будет возвращать список доступных библиотек(возможно такое уже есть, я не знаю), ведь конечную компиляцию и линковку всё равно будет осуществлять LLVM(у которой нет разницы между языками), а не сам язык. Так если все библиотеки в конечном счёте имеют вид байткода, у которого свой стандарт на всё и на вызываемые функции тоже, то какая разница, из какого языка этот байткод будет вызван ? Почему не предоставить всем языкам LLVM список экспортируемых функций другими языками ? Вообщем я не всё знаю об LLVM и не знаю, как это сейчас там работает.
>Спасибо за разъяснение, но вот по-моему эти биндинги ни к чему, я как раз за построение общего универсального АПИ между языками.Как бы вам объяснить то… Для этого сами языки должны быть адаптированы.
К примеру тот С++, что мэнэджет и в VC, ни разу ни анси Си. Это профанация. Код не переносим, что идёт в разрез с самой идеей языка Си.
Мс просто выкатило вам набор языков ДЛЯ своей платформы и всё.
Но это НЕ заслуга языков, а заслуга маркетинга мс. (Раз явно не глупый человек этого не понимает, то это вообще гениально. Честно. Но это же и отвратительно. Идею С и С++ кастрировали).Ну представьте если эти биндинги взяли и внесли в стандарт каждого из указанных языков.
Это конечно упростило бы задачу прикладных программистов, но не изменило бы сути ни разу.
> А в LLVM такую связь теоретически можно сделать через байткод.LLVM тут ничем не поможет, так как компилятор любого языка должен видеть определение вызываемой функции на этапе разбора исходного текста, иначе он просто не будет знать как скомпилировать вызов, для этого и нужны биндинги.
Дело в том, что у LLVM есть фреймворк для создания компиляторов, разработкики им пользуются для генерации байткода и вполне можно сделать так, чтобы этот фреймворк также предоставлял функцию, которая возвращает список экспортируемых функций. Если разработчик языка использует данную функцию, то он может видеть все внешние функции предоставляемые другими языками, которые можно будет использовать в программах на его языке.
> Дело в том, что у LLVM есть фреймворк для создания компиляторов, разработкики
> им пользуются для генерации байткода и вполне можно сделать так, чтобы
> этот фреймворк также предоставлял функцию, которая возвращает список экспортируемых функций.Ты не понимаешь, определение вызываемой функции нужно на уровне исходников, текстовый файл.
> Если разработчик языка использует данную функцию, то он может видеть все
> внешние функции предоставляемые другими языками, которые можно будет использовать в программах
> на его языке.Разработчик может видеть все что угодно, но пока функция не определена в исходниках, которые понимает какой-то язык, ты не сможешь ее использовать. И в функции llvm не входит генерация исходного текста биндингов для любого языка, хотя часть библиотек из шланга можно использовать чтобы что-то такое делать. Но llvm в любом случае тут не при чем, llvm не генерирует исходники на высокоуровневых языках, может разве что листинг на ассемблере выдать.
А компиляция вызова происходить будет на уровне байткода. В LLVM компиляторы языка просто генерируют неоптимизированный LLVM байткод. Функция LLVM фреймворка будет предоставлять полное описание экспортируемых функций, что будет достаточно компиляторам.Это всё теоретически, т.к. я не знаю, возможно, в LLVM уже так и сделано.
>COM-объект - это совсем другое, не то об чём я.
>И кстати мне интересно, какая в Линуксе технология, заменяющая COM?Во первых очень даже при чём. Это просто продолжение этой технологии.
На второй вопрос ответить сложнее. И вот почему — слишком большой круг задач, к которым эту технологию приспособили.
Но в оригинале COM-объект (тот что только с интерфейсом IUnknown) нужен только для одного — вызывать чужые блобы из своего ПО. Всё.
Опенсорс — это слишком креативно для корпорастов мс.Если рассматривать далее, то пожалуйте в технологии IPC и RPC.
Кстати, COM ничем не отличается в этом плане. Просто позаимствовала RPC (со своими изменениями) вот отсюда — http://ru.wikipedia.org/wiki/%D0%A3%D0%B... (и далее на DCOM), которую тоже можно использовать в своём ПО в linux (man rpcclient и даже http://www.bettina-attack.de/jonny/view.php/projects/php-msrpc/ ).
А вообще на текущий момент — dbus пожалуй стандарт (который теперь уже не демон, а в ядре. Спорное решение на мой взгляд, но вам понравится — теперь уж точно стандарт :D)
http://ru.wikipedia.org/wiki/Dbus (обратите внимание на вызовы методов. Там же ссылка на lor, где есть примеры) — как видите, писать можно на чём угодно и взаимодействовать с чем угодно.
> Приведу пример: Я хочу установить QT, после чего сразу же в Си
> заработает следующий код:Какое отношение QuickTime имеет к Си-коду, школота?
Проблема с .Net не то, что все языки на .Net будут одинаково быстро работать, а в том, что они будут одинаково тормозить. Но, как Вы правильно заметили, будут работать практически все и сразу (хотя, порой, исключения есть). С QT и традиционными компилируемыми языками код быстро будет работать гарантированно на одном языке (на котором писался), а вот для подключения библиотеки к другому языку приходится потрудится (хотя, не все так страшно, например, для того же Python или Lua). Но, потрудившись и скорость получим соответствующую.
Нормальным языкам типа Паскаль, такие извращения не нужны.
Разработчики Delphi и Lazarus забыли об этом тебя спросить и присобачили pascal к llvm.
llvm-pascal давно загнулся и не дышит.
Нет работающего транслятора pascal в llvm.
автор llvm-pascal не осилил pascal
Ребят, может кто подскажет, каким образом реализовать замыкания с помощью llvm?
https://github.com/llvm-mirror/clang/commit/e0e019fProfile-Guided Optimization (PGO) support is landing within LLVM's Clang C/C++ compiler in catching up to feature parity with GCC and their never-ending effort to improve performance of compiled binaries.
For those not normally excited by compilers, Profile-Guided Optimizations are a means of profiling a compiled program so that on subsequent compilations the compiler can better optimize the code for improved run-time performance. PGO is very different from traditional source-level optimizations and it's taken some time for Clang to implement the support besides the fact not many utilize this compiler optimization technique due to it being time intensive with requiring multiple compilations plus run-time profiling.
With a code commit that hit Clang mainline last week, there's now the initial instrumentation for Profile Guided Optimizations. While the code is still in early form, proper Clang PGO support will hopefully be a feature of LLVM 3.5.