Вы можете скачать бинарники и исходники здесь: http://releases.llvm.org/download.html#5.0.0
lli нужен для интерпретации промежуточного кода LLVM IR. Вы можете компилировать его утилитой llc и потом запускать, результат будет тем же самым
1. Нет, не путаю.
2. Компилятор, внезапно, имеет абсолютно детерминированный алгоритм оптимизации, который в каждом конкретном случае приведёт к конкретному поведению.
3. На эту тему можно долго и много рассуждать, скоро напишу ещё, кстати.
Для использования особенностей конкретного процессора есть как минимум два «законных» способа:
1) ассемблерные вставки (куда оптимизатор не лезет)
2) intrinsic-функции, которые для этого и существуют.
Всё это делает не clang, это делает opt, и вы можете отключить любой из проходов оптимизации. Или написать свой. По умолчанию всё работает так, как работает, и здесь бессмысленно возмущаться, потому что стандарты и алгоритмы оптимизации от этого не изменятся.
Если вам нужно сделать запись в массив, расположенный по адресу 0, объявите его как volatile. Компилятор не оптимизирует доступ к volatile-переменным.
> об указателе null, а не 0
#define NULL ((void *) 0)
Она избыточна, если присходит после разыменования указателя. То есть компилятор считает, что если указатель уже успешно разыменован, он не может быть нулевым.
Всё же попробуйте gcc, должно собираться.
lli нужен для интерпретации промежуточного кода LLVM IR. Вы можете компилировать его утилитой llc и потом запускать, результат будет тем же самым
2. Компилятор, внезапно, имеет абсолютно детерминированный алгоритм оптимизации, который в каждом конкретном случае приведёт к конкретному поведению.
3. На эту тему можно долго и много рассуждать, скоро напишу ещё, кстати.
темной стороны СилыUB избегать должен.Это про С, и во многом, про С++. UB — плата за скорость и эффективность.
1) ассемблерные вставки (куда оптимизатор не лезет)
2) intrinsic-функции, которые для этого и существуют.
> об указателе null, а не 0
#define NULL ((void *) 0)
>ИМХО, но тут явно недоработка компилятора.
Нет.