LINUX.ORG.RU

LLVM. Зачем он вообще нужен?

 ,


3

6

Я понимаю, зачем его используют: чтобы не писать 100500 раз в каждом компиляторе одни и те же алгоритмы оптимизации.

Я не понимаю, почему не использовать просто компиляцию через Си или Си++. Оптимизации сделает компилятор Си. Семантика у LLVM всё равно совпадает с Си, по объёму кода компилятора тоже выигрыша практически нет. Зато если использовать Си, можно использовать любой из компиляторов Си и компилировать для платформ, для которых нет реализации LLVM.

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

Стандарты же на то и стандарты что чётко определяют как и что, разве нет?

Для этого стандарты должны опираться на непротиворечивую теорию. А теориями, тем более непротиворечивыми, занимаются академики. Тебе нужен академический язык, который построен на основе теории (coq, agda и brainfuck, дада)?

Не говорю о том, чтобы железо тоже было построено на основе непротиворечивой теории, а не эти с виртуальной адресацией, с ring(-2), dma и прочей смесью архитектур фон Неймана, Гарварда и непонятно чего.

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

Доколе? Сколько десятков лет нужно чтобы стереть это грязное пятно из стандарта?

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

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

Стандарты же на то и стандарты что чётко определяют как и что, разве нет?

Да, в какой-то одной чётко очерченной области.

Наличие UB делает из стандарта в лучшем случае - методические рекомендации.

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

Уб - это норма для стандарта. Вот, возьмём к примеру стандарт на IP rfc791:

Address Formats:

      High Order Bits   Format                           Class
      ---------------   -------------------------------  -----
            0            7 bits of net, 24 bits of host    a
            10          14 bits of net, 16 bits of host    b
            110         21 bits of net,  8 bits of host    c
            111         escape to extended addressing mode

      A value of zero in the network field means this network.  This is
      only used in certain ICMP messages.  The extended addressing mode
      is undefined.  Both of these features are reserved for future use.

Видишь, extended addressing mode ? Он undefined. Это значит, стандарт про него ничего не говорит, и ты, не нарушая стандарт, можешь использовать этот режим для своих целей.

Вот, @hateyoufeel, например, при получении пакета с такой адресацией выведет себе на экран гигантский член.

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

Без макросов не требует. Вызов функции из разделяемой библиотеки спокойно делается и без компилятора C.

Если ты про ABI, то да, делается. Но кажется проще воткнуть функцию, которая вернет адрес errno, чем угадывать это каждый раз с выходом новой версии glibc.

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

Видишь, extended addressing mode ? Он undefined. Это значит, стандарт про него ничего не говорит, и ты, не нарушая стандарт, можешь использовать этот режим для своих целей.

Нет, не можешь. Потому что в следующем стандарте он будет определен и твоя срань начнет работать неправильно. Для того что ты хочешь, используется понятие «vendor-specific».

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

Но кажется проще воткнуть функцию, которая вернет адрес errno, чем угадывать это каждый раз с выходом новой версии glibc.

Или использовать компилятор Си++. Тогда проблемы с интеграцией нет. И не приходится делать сишные обвязки вокруг каждого метода каждой реализации шаблона класса.

А в случае, когда код на выходе должен выглядеть как

G_BEGIN_DECLS

/*
 * Type declaration.
 */
#define VIEWER_TYPE_FILE viewer_file_get_type()
G_DECLARE_DERIVABLE_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)

struct _ViewerFileClass
{
  GObjectClass parent_class;

  /* Class virtual function fields. */
  void (* open) (ViewerFile  *file,
                 GError     **error);

  /* Padding to allow adding up to 12 new virtual functions without
   * breaking ABI. */
  gpointer padding[12];
};

/*
 * Method definitions.
 */
ViewerFile *viewer_file_new (void);

G_END_DECLS

или как реализация класса Си++ с переопределёнными методами или слотами Qt, то и сишные обвязки не спасают, приходится половину макросов запихивать прямо в FFI. В лиспе можно хотя бы прямо во время компиляции сгенерировать вспомогательный файл c++ и подключить его к программе, а в чём-то менее настраиваемом только делать расширения языка и компилятора на каждую сложную библиотеку.

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

Проблема в том что сишный abi плюс-минус умеют все. Плюсовый abi это отдельная история плясок и половина проектов туда не захочет, и у нас будет уже два не самых хорошо спроектированных abi. В идеальном мире у нас был бы какой интероп стандарт, не привязанный к языку, но это уже граничит с протоколами сериализации и договориться о таком тоже вряд ли получится.

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

Проблема в том что сишный abi плюс-минус умеют все.

Кроме LLVM. В нём нет int и long.

Плюсовый abi это отдельная история плясок и половина проектов туда не захочет

Фактически, единственный способ получить плюсовый abi — компилировать язык через плюсовый компилятор. Потому что у разных плюсовых компиляторов разное плюсовое abi.

В идеальном мире у нас был бы какой интероп стандарт, не привязанный к языку

Microsoft COM. Но в Linux работает только через Wine.

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

Потому что в следующем стандарте он будет определен

  1. Или не будет.
  2. Я по-прежнему буду соответствовать прежнему стандарту, ЧТД.

Для того что ты хочешь, используется понятие «vendor-specific».

Нет, не используется. «vendor-specific» используется прямо в тексте стандарта тогда, когда стандарт прямо описывает механизм расширений для вендоров.

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

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

Или не будет.

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

Я по-прежнему буду соответствовать прежнему стандарту, ЧТД.

Ты по-прежнему не будешь ему соответствовать. Тебе просто продолжает везти, что эти битики никто не стал использовать. Более того, особо циничные реализация протокола могут считать твое сообщение невалидным из-за того, что эти значения зарезервированы и использовать их в актуальных версиях протокола нельзя.

Нет, не используется. «vendor-specific» используется прямо в тексте стандарта тогда, когда стандарт прямо описывает механизм расширений для вендоров.

Ага, это как раз то, что ты делаешь.

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

То что делаешь ты, называется «быдлокодерство».

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

Я по-прежнему буду соответствовать прежнему стандарту, ЧТД.

Ты по-прежнему не будешь ему соответствовать.

Назови нарушенный пункт стандарта.

То что делаешь ты, называется «быдлокодерство».

То что ты делаешь, называется тупизна и не способность проследить дискуссию дальше текущего поста.

Это буквально то, на что надеются сишники с UB.

Ох, лол. Сишники фактически не могут написать программу, которая бы не имела UB. Как ты с такими познаниями в предмете вообще вкатился в этот тред?

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

Назови нарушенный пункт стандарта.

Ты используешь зарезервированные поля. Ты сам дойдешь до словаря или мне рассказать тебе что значит «зарезервированный»?

То что ты делаешь, называется тупизна и не способность проследить дискуссию дальше текущего поста.

Киса ты что обиделась?

Ох, лол. Сишники фактически не могут написать программу, которая бы не имела UB.

Ты просто не шаришь:

#include <stdio.h>

int
main(void)
{
    puts("LamerOk не шарит");   
    return 0;
}

Показывай UB.

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

Мне кажется, ты чего-то не понял. Стандарт спроектирован с наличием грязного пятна.

Я действительно не понял почему сделали грязное пятно вместо явного бросания ошибок/исключений и почти 40 лет все делают вид что так и надо.

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

zero cost (тогда) всему виной

у си фактически нет рантайма(обязательного) всё что есть опцинально

ибо асм для всех железок такой самый подходящий

а ща легаси да и миллион мартышек уже привыкли к такому варианту «тут так принято» - более того зачем менять «латынь» если полно новых_языков

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

The extended addressing Mode is undefined. Both of these features are reserved for future use.

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

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

Исправляй UB.

Зачем ты это породил и что ты пытаешься этим доказать? Что ты не умеешь писать сишный код или пользоваться флагами компилятора, чтобы превратить это в человеческий врапинг?

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

неопределённость в американских стандартах оставляли для уточнения в следующих итерациях

Нет, не всегда. В случае с Си - точно нет.

почему сделали грязное пятно вместо явного бросания ошибок/исключений и почти

Потому что стандарт языка не написан для разработчиков языка. Стандарт написан для разработчиков компиляторов. А для программистов на языке написана документация к их целевому оборудованию и компилятору + бибилиотекам. Стандарт им нужен только для поиска бага в последних.

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

Назови нарушенный пункт стандарта.

Ну он прав в том что если используется то что находится ВНЕ стандарта то результат никак не будет ему соответствовать. Тоже самое с UB.

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

Сишники фактически не могут написать программу, которая бы не имела UB.

Зачем ты это породил и что ты пытаешься этим доказать?

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

Киса ты что обиделась?

Нет, киса думает, стоит ли дальше отвечать на твой тупняк. Я даю тебе шанс:

ты не умеешь писать сишный код

Ну покажи всему миру как надо складывать два числа на си без UB.

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

zero cost (тогда) всему виной

все в округе говорили,
этой странной UB,
этой странной UB,
так ему и не простили...

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

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

Соответствовать стандарту == не нарушать его требований. Только и всего.

Если стандарт говорит - вот это вот будет UB, а программист использует, это не нарушение? (это кстати краеугольный камень непонимания логики)

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

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

Я не собираюсь разбираться в том что хотел сказать автор. Либо ты пишешь, что хочешь сказать, либо мечешься по форуму и орешь что тебя никто не понимает. Pick your poison.

Ну покажи всему миру как надо складывать два числа на си без UB.

<stdckdint.h>

or

-fwrapv

Остальное пережитки прошлого и не нужно.

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

Соответствовать стандарту == не нарушать его требований. Только и всего.

Ты их нарушил, начав использовать зарезервированные поля. Завтра выйдет новый RFC, куда напишут «если бит N выставлен, значит автору надо послать вагон резиновых членов за его счет». И все, и ты в долговой яме заваленной резиновыми членами.

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

Так LLVMнутые то же самое, категорически против отвязывания фронтендов от своего зонда. А LLVM-IR да, используйте как хотите.
Хотите в VM интерпритируйте как макроассемблер (плохо подходит? А нам насрать), хотите компиляйте специфическим образом под свои vliw /gpgpu/cell (не хватает таргет-специфик информации? Ну придумайте чегнить выкрутитесь)

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

Brainfuck – это высокоуровневый язык или нет?

Низкоуровневый. В принципе, он не сильно от ассемблера отличается. Набор команд только очень маленький и не привязан к какой-то конкретной машине.

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

в си нет массивов… «Си-массив» это синтаксический сахар…

Память то под этот «массив» выделяется. Так что это не просто указатель. Но перемещение по этому «массиву» программой не контролируется, да. Операционный системе может не понравиться, что мы лезем в чужую память и она прервёт выполнение программы. Но это уже другой вопрос. Да и не везде ОС есть.

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

Если стандарт говорит - вот это вот будет UB, а программист использует, это не нарушение?

Ещё раз медленно и печально - вот программа на Си, которая приводит к UB.

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

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

int add(int a, int b)

Я когда-то использовал информацию по ссылке. Но иногда это излишне. Например, у нас прошивка микроконтроллера считает скользящее среднее по данным АЦП. Мы знаем, что это АЦП выдаёт от 0 до 255. Соответственно, мы можем сказать, что сумма из 4, например, замеров не переполнит 16-битное целое. Контроль переполнения не нужен.

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

@hateyoufeel случайно не приходится тебе родственником?

Думаешь у нас семейная монополия на шутки про члены? Патентованые членовые скоморохи? Раскусил. Теперь с каждой членошутки ты нам должен платить роялти. Не заплатишь — отправишься в яму.

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

Тогда почему вы не используете uint8_t, лол?

uint8_t для суммы тоже, вероятно, можно использовать. Просто алгоритм сложнее будет. Либо в точности проиграем. С uint16_t проще и быстрее.

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

У С++ вообще нет ABI.

У всего что запускается на компьютере есть бинарное представление какое-то. Какой-то там манглинг есть, у некоторых недоязычков. Это никто кроме недоучек не называет ABI.

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

array это не массив, это «куча». То есть свалка данных на стеке либо в памяти с условными границами. Это не синтаксический сахар.
Массивы в си предполагается что ты напишешь сам как нибудь вот так:

#define arr_begin(a) &a.buf[0]
#define arr_end(a)   &a.buf[a.size]

struct arr {
    char buf[255];
    int size;
}

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

вот вот COMMON BLOCK as is

всёж сяшка не с неба упало там фортран все умели

токмо прогресс есть поэтому вот эти именованные комонблоки не только статик в глобальных; но и на стеке динамично; ну а ежель какой m(памяти)alloc(датель) есть так чистый сахар

т.е. как и весь С(плод гения РичиТомсона) набор не ортогональных эвристик и адхоков приспособленных для переноски ядра расширенной машины

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

объективно в си нет массивов

А где есть? Семантика

char *s;

и

char s1[100]

заметно отличается. s и s1 не взаимозаменяемы.

Сяшка это асм - за то и

Нет. В асме нет UB.

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

Сяшка это переносимый асм поэтому та часть которая заведомо общая у тех обычных процов - то детерменированно в сяшке то что платформо обусловленно частично UB

не будь уже устоявшегося протокола установления остро-тупо-конечности или вообще перемешаные байта в 4байтовом слове - это тоже было бы UB

и если уж совсем лезть в дебри - на процах есть UB - недокументированные команды наличие которых не гарантированно

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

Сяшка это переносимый асм

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

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

на процах есть UB - недокументированные команды наличие которых не гарантированно

И в чем здесь UB? У тебя либо выполнится команда, либо процессор скажет тебе, что ты баклажан.

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

то детерменированно в сяшке то что платформо обусловленно частично UB

Нет. Есть UB не от платформы.

Например:

int data[10];

int find(int x)
{
  int i;
  for(i = 0; i <= 10; i++)
    if(data[i] == x) return 1;
  return 0;
}

На любом ассемблере

find(1) && find(2) && find(3) 
  && find(4) && find(5) && find(6)
  && find(7) && find(8) && find(9)
  && find(10) && find(11) && find(12) == 0

потому что в data[0]…data[10] всего 11 значений, а значит find хотя бы для одного из 12 значений должен вернуть 0. Но на Си он будет возвращать 1 для всех значений.

monk ★★★★★
() автор топика
Ответ на: комментарий от monk
int data[10];
...
for(i = 0; i <= 10; i++)

Во первых у тебя выход за границы массива.
Во вторых я не понял, что ты пытался сказать.
В третьих, не понятно, с чего

Но на Си он будет возвращать 1 для всех значений.

?

LamerOk ★★★★★
()
Ответ на: комментарий от monk
#include <stdio.h>


int data[10];

int find(int x)
{
  int i;
  for(i = 0; i <= 10; i++)
    if(data[i] == x) return 1;
  return 0;
}


int main ()
{
  int a = ((find(1) && find(2) && find(3)
	   && find(4) && find(5) && find(6)
	   && find(7) && find(8) && find(9)
	   && find(10) && find(11) && find(12)) == 0);

  printf("= %d\n", find(1));
  printf("= %d\n", find(2));
  printf("= %d\n", find(3));
  printf("= %d\n", find(4));
  printf("= %d\n", find(5));
  printf("= %d\n", find(6));
  printf("= %d\n", find(7));
  printf("= %d\n", find(8));
  printf("= %d\n", find(9));
  printf("= %d\n", find(10));
  printf("= %d\n", find(11));
  printf("= %d\n", find(12));


  printf("%d\n", a);
}

= 0
= 0
= 0
= 0
= 0
= 0
= 0
= 0
= 0
= 0
= 0
= 0
1

nionio35
()