Почему линуксовые компиляторы ошибаются?
just a guest 18 января, 2011 - 13:10
Почему не рекомендуеться собирать с максимльным флагом производителности? Я просто не понимаю -- как компилятор может собрать не рабочую программу? Ведь тогда это не правильный компилятор, правильно? Значит он где-то просчитался, возможно адрес не правильно написал, а для прог это фатально.
Или вот еще: порылся в нете насчет сборки системы с ICC и нашел фразы типа "ядро можно даже не пытаться с ним собирать","архиватор собираеться, и даже работает, но при попытке открыть архив говорит, что тот поврежден. Хотя архив вполне рабочий...". По-моему в исходниках довольно ясно описываеться - что, куда и зачем. Так как же тогда можно собрать архиватор, что он не открывает архивы?
»
- Для комментирования войдите или зарегистрируйтесь
1. Который флаг отвечает за
1. Который флаг отвечает за максимальную производительность ? И если можно то для разных платформ.
2. напишите хелло ворд и погоняйте на разных компиляторах
just a guest
что за флаг?
компилятор не может создать нерабочий код, есть программисты и горе-оптимизаторы, которые могут заставить его это сделать :)
для того, чтобы прикручивать запчасти от жигулей к иномаркам так, чтобы это работало, надо иметь очень прямые руки и высокопрецизионный напильник ;) (с)
другими словами, код написанный для gcc, не обязан компилироваться ICC и наоборот... изучи С/С++ и сам все поймешь ;)
Theli написал(а): для того,
код написанный следуя стандарту _обязан_ компилироваться любым компилятором поддерживающим этот стандарт.
Однако ядро и некоторые программы используют нестандартные хаки, в частности gcc builtin функции, которые повышают производительность, понижая портабельность.
Это касается всех
Это касается всех компиляторов, а не только линуксовых.
Во всех программах есть ошибки, и чем сильнее программа оптимизируется во время компиляции, тем больше шансов, что эти ошибки проявятся. К тому же, хотя С/С++ везде одинаковый, но каждый компилятор может поддерживать свои дополнительные фичи.
Поэтому лучше всего программа компилируется и работает под каким-то одним компилятором(тем который использовал человек ее писавший). Но есть примеры, когда поддерживается несколько.
Действительно, попробуйте написать программу строк 100-200 и скомпилировать под разными компиляторами и/или версиями одного.
_SerEga_ написал(а): К тому
это не совсем так.... вернее они только выглядят одинковыми ;) есть стаднарты C89(ANSI C), есть ISO C (ISO/IEC 9899:1990), есть C99 (ISO 9899:1999)... и они все чем-то отличаются ;) есть всякие фишки и плюшки, которые добавляются компиляторами, и даже фишки, которые доавляются библиотеками, например Qt ))
Я это и имел ввиду. Про
Я это и имел ввиду. Про "фишки, которые доавляются библиотеками" не понял.
Qt частично вводит свой
Qt частично вводит свой синтаксис в описание классов, свойст классов и т.д., которые перелопачиваются препроцессором moc ))
хотя, возможно, что это не совсем то ))
Theli написал(а):_SerEga_
ICC считаеться коммерческой (относительно - для некоммерчесих применений он бесплатный) заменой GCC для Интел процессоров, следовательно все библиотеки GCC'вские должны поддерживаться и в нем.
Все равно не понимаю. Беру самый простой пример: можно скомпилировать так
, а можно так:
Но в любом случае это будет работать. А как сделать что бы не работало? По моему очевидно просто ошибиться. Или я все таки что-то не правильно понимаю?
Так ведь в последний раз стандарт менялся аж в 99-ом.:) Я думаю сейчас все придерживаються одного -- последнего. И даже если не так -- у ICC и GCC наверняка один стандарт. Кроме того проги с разными стандартами скорее всего просто не скомпилируются -- а здесь речь, что компилируются, но не работают.
Да, интересная статейка.
P.S.
Блин, жал же "добавить комментарий" а не "ответить". Чего ж он его в самый низ не скинул...
http://ru.wikipedia.org/wiki/
http://ru.wikipedia.org/wiki/Intel_C%2B%2B_compiler
Думается, мне самые простые примеры будут работать при любых оптимизациях ;)
Если человек пишет - компилируется, но не работает, может оказаться, что изначально он не компилировалось, а потом, когда он исправил тривиальные "ошибки"(на самом деле не ошибки, а просто разные стандарты) и уже после этого оно скомпилировалось и не работает. Т.е. он исправил не все, а только то, что не давало компилироваться.
Я согласен, что с большой вероятностью причина не работы - ошибка, но совсем не обязательно в компиляторе, ошибка в программе может приводить к аналогичным результатам.
Сам в этом не разбираюсь, но читал:
http://www.insidepro.com/kk/231/231r.shtml
т.е. ни копилятор, ни прога не виноваты.
_SerEga_ написал(а): Во всех
Дело не в ошибках в программе, а в ошибках в самом компиляторе. -O2 это как stable optimization, очень маловероятно, что вы наткнетесь на баг gcc используя этот уроень. А -O3 включает в себя еще не достаточно протестированные оптимизации. Я так понимаю, что в процессе тестирования, когда какой-либо флаг оптимизации становиться достаточно стабильным, его включают в -O2.
Если создатель/тестер проги
Если создатель/тестер проги использовал тот, же гцц и то же окружение и т.д. то да, аналогично про О3, если прога исходно компилируется при O3.
ps Ни разу не сталкивались, что прога правильно работающая в режиме отладки начинает сбоить при компиляции с О2?
_SerEga_ написал(а): ps Ни
Сталкивался, но это связано было с тем что в режиме дебага иначе память выделялась, в конечном итоге это был некорректный код(который по случайности изза особенностей выделения памяти не сбоил), после исправления бага в этом коде он стал работать нормально и без дебага, компилятор в данном случае вел себя совершенно корректно.
А если использовать -O3 то к багам программиста добавляются баги компилятора.
Гарантировать отсутствие
Гарантировать отсутствие ошибок не может никто.
Может быть, если найти оставшиеся ошибки и исправить,то он при О3 будет работать правильно?
зато можно гарантировать
зато можно гарантировать наличие ошибок, поэтому если разработчики компилятора говорят, не используйте -O3 там где важна стабильность, то не стоит его использовать или рискуете получить многочасовой гемморой с отладкой собственного кода, в котором нет ошибок, если вы разработчик или получить неработающую программу из корректного исходника, если вы пользователь программы.
У меня долгое время была
У меня долгое время была собрана система с О3 и все прекрасно работало. А есть пакеты которые в любом случае компилируются с О3 Т.е. некоторым разработчикам удается писать код работающий с О3.
К тому же сейчас не рекомендуют глобально использовать О3, т.к. может приводить к замедлению работы.
Чего ж тогда была? ;) почему
Чего ж тогда была? ;) почему в прошедшем времени? ;)
Покажите мне пакет в генту, который безусловно компилируется с -O3, (то есть если вы не выставили в флагах компилятора). Зато есть целая куча примеров, когда делают наоборот - выкидывают -O3 даже если "умный" пользователь поставил его в флагах компилятора.
Зачем мне значительное
Зачем мне значительное увеличение времени компиляции, да еще при присутствии риска замедления работы: поэтому и была.
как встречу скажу, т.к. не контролирую какой пакет с какими флагами ставиться, только изредка поглядываю, как идет процесс сборки. Несколько раз видел проскакивало O3, когда у меня стояло О2.
Не уверен, что оно(нашел за 3 минуты grep), но /usr/portage/media-video/projectx/projectx-0.90.4.00_p33.ebuild
Разработчику виднее, как лучше.
gry написал(а): Покажите мне
Легко (таких пакетов полно), ну вот вам навскидку - www-client/chromium. Пакет очень объёмный (за 100M) и во время довольно длительной компиляции прекрасно видно, как часть (бОльшая) составляющих его модулей сами себе берут флаг -О3
Мы тоже не всего читали Шнитке!.. © В. Вишневский
mplayer с -O4 вообще
емнип, mplayer с -O4 вообще собирается )))
Мда
Theli - память тебе изменяет. Проверка - sudo emerge mplayer | tee mplayer.log
Spoiler - "довольно длительной компиляции"? Это когда начинает компилиться http://code.google.com/p/o3d и кажется, что САМ включился -O3? o3d vs O3. Проверка sudo emerge chromium | tee chromium.log
а эта строка - это просто подпись
n0nado написал(а): Theli -
ну, щас у меня mplayer-9999 и он собирает с моими CFLAGS/CXXFLAGS... ели скажешь как сделать, чтобы он с умолчальными настройками собирался, я проверю ;)
UPD:
т.ч. при некоторых обстоятельствах mplayer задействует -O4 ;) правда я видел такое в последний раз оооочень давно... видимо до перехода на 9999 :)
Интересно, что значит -О4.
Интересно, что значит -О4? Где-то видел, что для gcc все что больше О2 это О3
.
Блин. То, что для проверки поддержки FAAC запускается "cc_check -O4" не означает вашего "емнип, mplayer с -O4 вообще собирается".
Сделайте sudo emerge mplayer | tee mplayer.log и посмотрите, причём сделайте именно с вашими CFLAGS/CXXFLAGS а не умолчальными.
Так что не надо вот этого "при некоторых обстоятельствах mplayer задействует -O4" - оно только путает всех. Вот уже и _SerEga_ запутался
а эта строка - это просто подпись
nOnado, не надо!!! (с) все,
nOnado, не надо!!! (с)
все, что я хочу сказать, что -O4 существует и где-то используется... щас mplayer собирается с моими CFLAGS, но раньше я отвечаю, что он собирался с -O4 хотя бы местами... я точно помню, что год или два назад уже гуглил на тему -O4, но понял только, что это включает межпроцедурную оптимизацию... возможно в mplayer что-то изменилось, возможно опции, которые включались в -O4 перешли в -O3 или -O2, вот и не используется теперь - я не знаю! но что -O4 использовалось в mplayer для меня факт и никто меня в обратном не переубедит ;)
n0nado написал(а):Это когда
Нет
Эка куда это вас понесло?!?
Зачем вы это нарисовали мне?- в данном конкретном случае для меня неясностей нет, это вы проверяйте, если не лениво (chromium-10..., x86_64)
Насчёт того, что где-то используется - почему бы нет, кто запретит "использовать" хоть -O65535? А вот GCC знает о существовании лишь -O -O0 -O1 -O2 -O3 -Os (см. мануал GCC)
Мы тоже не всего читали Шнитке!.. © В. Вишневский
Вот почитать для
Вот почитать для поверхностного представления
http://www.insidepro.com/kk/119r.shtml
Эквивалентность
Добрый день, дамы и господа. Возможно мой комментарий немного не к месту, однако.
Код написанный программистом, и код сгенерированный компилятором - два разных кода. Только они эквивалентны с математической точки зрения. Вернее, должны быть эквивалентны. А вот с этим у компиляторов и могут возникать проблемы. Причем, у каждого свои. И проблемы увеличиваются, когда "умные" программисты начинают помогать компилятору оптимизировать код. Так что компилятор может совершенно спокойно собрать нерабочую программу и рабочего исходника.
Вот.
Не смог пройти мимо. Исходя
Не смог пройти мимо.
Исходя из упоминания ICC ты говоришь в первую очередь о C/C++. В этом случае ответ не очевиден.
Во первых, конечно, в компиляторах есть ошибки. Авторы компилятора не в состоянии проверить всё. Ради любопытства можно например почитать http://refu.ru/refs/67/14960/1.html или http://www.ipmce.ru/about/press/popular/potencial4-2007/ т. о. даже если у тебя правильная программа и правильно скомпилирована - не факт, что будет работать правильно.
Во вторых в самом стандарте есть неоднозначности в порядке обработки данных. Там всё строиться на понятии, что к такому-то моменту все значения должны быть вычислены. Однако, что происходит в промежутке - стандарт не оговаривает и оставляет на откуп компилятору. Пока компиляторы были простые, программисты не изгалялись с не очевидной оптимизацией, машины однопроцессорные и т. д. и т. п. всё было ничего, однако пришло время и началось. В новой версии компилятора программа не правильно работала. Костыли приделывают с обоих сторон. Пытаются научить компиляторы обнаруживать такие ситуации. Исправляют программы.
В третьих. Для языков C/C++ нет набора тестов оговоренных в стандарте. т.е. любая поделка школьников имеет право так называется. Например, для языка Ada это не так.
Ну и на последок ответ на твой вопрос - на низких (рекомендованных) уровнях оптимизации вероятность нарваться на всё это добро гораздо ниже.