|
|
  |
Странности при оптимизации |
|
|
|
Dec 23 2008, 12:40
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Кстати, раз уж о глюках: У меня при включенной оптимизации компилятор думает, что раз тела у while нет, то можно и зациклить сам на себя БЕЗ проверки условия, т.е. MojBit=1; while(MojBit==1) { }; в асме выглядит так: Addr: rjmp Addr Если в тело хотя бы вставить _NOP(); т.е. while(MojBit==1) {_NOP();}; картина меняется - добавляется загрузка вита в 1 и проверка в теле while. Вопрос знатокам: Почему? Компилятор умнее пользователя? Модератор. Тема выделена как отдельная из другого топика.
|
|
|
|
|
Dec 23 2008, 18:37
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(Палыч @ Dec 23 2008, 15:52)  Почему картина поменялась после добавления _NOP(); - не скажу, вроде на условие в цикле не влияет... А, вот, проверять условие цикла - нет необходимости: переменной MojBit присвоено значение 1 и условие MojBit==1 - всегда выполняется! Не согласен. Вы забыли про прерывания? Вот они и меняют этот бит. Может компилёру нужно дополнительно сообщить, что этот бит ещё где-то может модифицироваться? Вопрос, как... P.S. Я с асмом дружу очень, но большие модули переписываю на С, потому что надоело при смене типа мк в пределах одного изготовителя приходится сильно менять исходник, а при смене Z80<>PIC<>Holtek<>AVR<>msp430<>PC<>mcs48<>mcs51 и т.д. просто волосы дыбом встают... Поэтому и прошу помощи... Как было указано в начале темы, мож у мя глюки? 2Moderator: Может мне создать отдельную тему? Но я её хотел назвать именно так, как назвал автор
|
|
|
|
|
Dec 23 2008, 19:16
|
Частый гость
 
Группа: Свой
Сообщений: 79
Регистрация: 8-04-05
Из: Санк-Петербург
Пользователь №: 3 972

|
Цитата(DenisIV @ Dec 23 2008, 21:37)  Вы забыли про прерывания? Вот они и меняют этот бит. Может компилёру нужно дополнительно сообщить, что этот бит ещё где-то может модифицироваться? а прочитать тему с самого начала? при объявлении своей переменной MojBit укажите что она volatile и будет вам счастье
|
|
|
|
|
Dec 23 2008, 23:21
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(sergeeff @ Dec 24 2008, 01:38)  Просто не устаю поражаться. На нашем форуме про volatile уж было все рассказано, подробнее, чем где-бы то ни было, учитывая специфику программирования железа. Ан нет, есть еще граждане про сие не читавшие, да еще и вопрос задающие не поймешь как. Чудно, все это. Прошу простить... Это как допустим чья-то жена получила вчера права, начинает спрашивать мужа: "Как там решить вопрос с ГАИшниками, если..." Муж: "Я ж те говорил, книжки покупал..." На сколько я знаю, volatile говорит компилятору о том, что все связанные с переменной действия ни в коем случае не оптимизировать. Вопрос для многозадачных или "мощных" систем вроде выглядит по другому: требуется ещё лочить переменную на время обработки данных(например в прерывании меняется массив данных и указатели на него а основная прога может вылететь) И если можно про static. Просветите плиз тонкости... Может быть еще раз... Ну "я месяц назад получил права"
|
|
|
|
|
Dec 24 2008, 01:12
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(DenisIV @ Dec 24 2008, 03:21)  Прошу простить... Это как допустим чья-то жена получила вчера права, начинает спрашивать мужа: "Как там решить вопрос с ГАИшниками, если..." Муж: "Я ж те говорил, книжки покупал..." На сколько я знаю, volatile говорит компилятору о том, что все связанные с переменной действия ни в коем случае не оптимизировать. Вопрос для многозадачных или "мощных" систем вроде выглядит по другому: требуется ещё лочить переменную на время обработки данных(например в прерывании меняется массив данных и указатели на него а основная прога может вылететь) И если можно про static. Просветите плиз тонкости... Может быть еще раз... Ну "я месяц назад получил права"  Во-первых, понять, что если есть в системе прерывания и вы их используете - значит уже система многозадачная. Во-вторых. Что значит "приказ не оптимизировать"? Это значит, что какая-то другая задача тоже может эту переменную использовать, а по сему эта самая переменная будет размещена в памяти, а не в регистрах. Вопрос о том, "лочить" или нет эту переменную - вопрос ее размера и особенностей процессора. Если обращение к ней проходит за время, когда прерывание не может возникнуть, то и "лочить" не нужно.
|
|
|
|
|
Dec 24 2008, 02:56
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
2rezident: со static (и не тоько) разобрался, спасибо! Ещё вопросик... Насколько я понимаю, у меня эти проблемы с оптимизацией начались после того, как у меня образовалось более одного модуля, т.е. каждый модуль независим для компилятора и компилёр оптимизирует не проект, а данный модуль и если я в одном модуле только читаю а в другом только пишу переменную, то в обоих случаях если я не допишу volatile компилёр просто выкинет эти строки (просто примет за константу данные при компиляции), а с линкера не спросишь-он просто склеит готовые блоки. Опять же, если будет это всё в одном файле/модуле, то даже при макс. оптимизации компилёр может понять, что переменная юзается внутри в разных функциях (в т.ч и в прерываниях) и не будет оптимизировать до упора? Т.е. в данном случае не нужен тип global/static/volatile ? (модуль-то один, global итак будет автоматом, вопрос только про оптимизатор) Да, самое интересное: Я объявляю в модуле main глобальные переменные, в остальных модулях их же, но через extern, т.е. получается, что глобально в пределах проекта, но вот эта заноза-оптимизатор видит только в пределах модуля переменную (в смысле её использования), а не в пределах проекта? Или есть тонкости? Объясните плиз, где грабли... Крыша уже течёт... Просто я не умею их готовить... (с) какая-то реклама Чем-то чувствую, что и прав и нет. Хотелось бы понять, где. Я понимаю, RTFM, но всё же... F1 ! То, что люди задают глупые вопросы не означает, что они глупы, просто иногда не хватает опыта... Сорри, если чуть оффтоп...
|
|
|
|
|
Dec 24 2008, 12:55
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(sergeeff @ Dec 24 2008, 15:41)  Я все не пойму, что за проблемы "с этой оптимизацией"? Где конкретно, с чем проблемы? Что компилятор делает не так, как вы хотите? Каждый модуль независим для компилятора и компилёр оптимизирует не проект, а данный модуль и если я в одном модуле только читаю а в другом только пишу переменную, то в обоих случаях если я не допишу volatile компилёр просто выкинет эти строки (просто примет за константу данные при компиляции) Вот в этом и грабли. Всё могло быть хорошо, если модуль один. (Вроде бы)
|
|
|
|
|
Dec 24 2008, 14:13
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(DenisIV @ Dec 24 2008, 15:55)  Каждый модуль независим для компилятора и компилёр оптимизирует не проект, а данный модуль и если я в одном модуле только читаю а в другом только пишу переменную, то в обоих случаях если я не допишу volatile компилёр просто выкинет эти строки (просто примет за константу данные при компиляции) Нет. Компилятор ОБЯЗАН обеспечить состояние переменных, видимое с точки зрения программиста, в любой точке программы. volatile всего лишь заставляет компилятор считать, что состояние переменной может быть изменено не только тем, что написанно в программе. Т.е. компилятор не имеет права выкидывать любые записи и чтения этой переменной. Но он не обязан каким либо другим способом синхронизировать доступ к ней - это обязанность программиста. Например, если мы имеем код Код a=1;
...
a=2;
...
a=3; то для не volatile переменной компилятор может оставить только последнее присваивание (если в промежутке не было вызовов других функций), для volatile все присваивания останутся Цитата Вот в этом и грабли. Всё могло быть хорошо, если модуль один. (Вроде бы) От количества модулей это не зависит. А вот качество оптимизации может зависеть.
|
|
|
|
|
Dec 24 2008, 15:47
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(XVR @ Dec 24 2008, 17:13)  Нет. Компилятор ОБЯЗАН обеспечить состояние переменных, видимое с точки зрения программиста, в любой точке программы. volatile всего лишь заставляет компилятор считать, что состояние переменной может быть изменено не только тем, что написанно в программе. Т.е. компилятор не имеет права выкидывать любые записи и чтения этой переменной. Но он не обязан каким либо другим способом синхронизировать доступ к ней - это обязанность программиста. Например, если мы имеем код Код a=1; ... a=2; ... a=3; то для не volatile переменной компилятор может оставить только последнее присваивание (если в промежутке не было вызовов других функций), для volatile все присваивания останутся От количества модулей это не зависит. А вот качество оптимизации может зависеть. Согласен. А есть ли возможность указать компилятору в данном конкретном примере какой-нибудь командой #cmdxxx НЕ ОПТИМИЗИРОВАТЬ например именно строчку где a=2; ?
|
|
|
|
|
Dec 24 2008, 23:00
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sergeeff @ Dec 25 2008, 01:09)  К примеру К "примеру" Вы уже говорили: Цитата сравнив ассемблерный листинг, генерируемый компилятором и дизассемблированный код. Так что замечания насчет оптимизации на уровне модуля тоже не совсем правомочны. А вот это: Цитата и это позволяет "отодвинуть" вопрос о встраивании функции или использовании обычного вызова на этап линковки. уже не имеет нималейшего отношения ни к обсуждаемой "проблеме", ни к Вашим предыдущим словам. Не говоря уже о том, что это вполне бесполезный трюк, ибо не позволяет произвести сквозную оптимизацию "склееенного" кода, а только грошовую экономию вызова. Любой компилятор сделает СВОЮ работу по inline несораизмеримо лучше, при этом КОМПИЛЯТОР должен предавительно изменить calling conversion для тех функций которые предполагается потом возможно склеить.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 25 2008, 07:17
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(sergeeff @ Dec 25 2008, 04:16)  Я не являюсь разрабочиком компиляторов и линкеров. Я являюсь Цитата Все вышесказанное привел только для иллюстрации того, что на сегодняшний день не только компилятор, но и линкер совместно оптимизируют генерируемый код. Это не совсем точное высказывание  Код может оптимизироваться на этапе линковки, но занимается этим не линкер, а все таки компилятор. И тот 'код', который оптимизируется, на самом делен не код, а промежуточное представление компилятора. Цитата Это может кому-то нравится, а кому-то нет. Вне зависимости от того, нравится это или нет, оптимизациями занимается компилятор, когда бы он не запускался Пример: Hi-TECH PICC-18 Pro. Результатом независимой компиляции модуля (.c) является файл (.p1) с промежуточным представлением С'ной программы. На этапе сборки (линковки) они ВМЕСТЕ обрабатываются компилятором, который и генерит выходной код. Другой пример: Intel C компилятор. Опция -ipo (или -fast) переводит компилятор в режим компиляции всей программы. При этом, компиляция собственно модулей (.c) производит .obj файлы, в которых НЕТ кода, зато есть секции с промежуточным представлением программы. На этапе линковки снова вызывается компилятор, который читает все это из .obj файлов и генерирует код (в виде одного .obj файла, на этот раз с кодом) который уже и отправляется линкеру. Что касается опции 'MSVC++ 7.0 /ltcg' то сдается мне, что это не опция линкера, а опция ВСЕГО проекта, и подавать ее надо везде. Реализация (скорее всего) будет очень похожа на реализацию в Intel компиляторе Единственная известная мне 'оптимизация' именно ЛИНКЕРА - это выкидывание неиспользуемых кодов и данных из исполняемого файла. Но у меня язык не повернется назвать это 'оптимизацией'
Сообщение отредактировал XVR - Dec 25 2008, 07:19
|
|
|
|
|
Dec 25 2008, 13:17
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(defunct @ Dec 24 2008, 20:09)  #pragma optimize = none Спасибо. Это как раз и было нужно. А опять включить ? Или можно поменять степень оптимизации на ходу?
|
|
|
|
|
Dec 25 2008, 13:36
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(Сергей Борщ @ Dec 25 2008, 16:24)  Вы двигаетесь в неправильном направлении. Правильно написанная программа должна работать при любом уровне оптимизации. Согласен. Но в данном случае вы неправы. Бывают разные ситуации. Я, например в данном случае пытаюсь добиться результатов после дилетанта-программиста. Возможности переписать ВСЮ прогу просто нет, отключаю оптимизацию=прога не влазит в кристалл. Программист в прерываниях использует почти все модули и я исправляю ошибки доступа, что бы основная прога не вешалась. Так что в данном случае мой вопрос правилен. Лично я пишу, правильно разбивая ресурсы/переменные и лично у меня проблем с оптимизацией не было. Просто исправлять за кем-то - неблагодарное и трудное занятие. Но необходимое (в моём случае)
|
|
|
|
|
Dec 25 2008, 21:19
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Ещё вопросик: Например, компилятор HiTech предупреждает при: Код while(1) { .... } while(1) { .... } типа warning: infinity loop, а вот ИАР не предупреждает, а молча делает...  Но это лирика... У меня (в данном случае ИАР) ругается на переменные, когда я их обзываю volatile на то, что он не может просчитать их значение, т.к. не проинициализированы. А инитить я их не хочу, т.к. эти переменные лежат в озу и должны быть валидны и просле ресета (я их инициализю отдельно, считая их CRC или анализируя флаг сброса по питанию) Вот тут и грабли... (Опять повторю, прогу полностью переписать не cмогу(высшая математика), исправляю за самоучками  )
|
|
|
|
|
Dec 25 2008, 22:14
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(rezident @ Dec 26 2008, 00:38)  DenisIV, а такой вариант объявления Код __no_init volatile unsigned a, b, c; не проходит? У меня IAR только "варнингами" ругается, но ошибок не выдает. Проходит,ошибок нет, вот по этому и спрашиваю, как обойти... Варнинги достали (>100)  Мож #pragma optimize =none ? Ток я не знаю, как потом включить и будут ли варнинги дальше? А у меня варнинг-указание на засаду в проге. Игнорировать и отключать не хочется... Потом можно 3 дня глюк ловить... И не поймать...
|
|
|
|
|
Dec 25 2008, 22:26
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(DenisIV @ Dec 25 2008, 23:19)  типа warning: infinity loop, а вот ИАР не предупреждает, а молча делает...  Но это лирика... Это не лирика, это где-то у вас преднамеренно отключены предупреждения (Project->Options->C/C++ compiler->Diagnostics): Код void Test() { while(1) { __no_operation();} while(1) { __no_operation();} }
Warning[Pe128]: loop is not reachable from preceding code D:\****\loader.cpp 75 Цитата(DenisIV @ Dec 25 2008, 23:19)  У меня (в данном случае ИАР) ругается на переменные, когда я их обзываю volatile на то, что он не может просчитать их значение, т.к. не проинициализированы. Давайте так: Есть непонятка, выкладываете код, выкладываете полный текст предупреждения на языке оригинала, будем смотреть. Код volatile int a; volatile int b; volatile int c; void Test() { int Tmp = a; b = Tmp; Tmp = b; c = Tmp; }
Done. 0 error(s), 0 warning(s)
\ In segment DATA_Z, align 4, align-sorted 72 volatile int a; \ a: \ 00000000 DS8 4 73 volatile int b; \ `b`: \ 00000004 DS8 4 74 volatile int c; \ c: \ 00000008 DS8 4
\ In segment CODE, align 4, keep-with-next 75 void Test() 76 { 77 int Tmp = a; \ ??Test: \ 00000000 0248 LDR R0,??Test_1 ;; a \ 00000002 0168 LDR R1,[R0, #+0] 78 b = Tmp; \ 00000004 4160 STR R1,[R0, #+0x4] 79 Tmp = b; \ 00000006 4168 LDR R1,[R0, #+0x4] 80 c = Tmp; \ 00000008 8160 STR R1,[R0, #+0x8] 81 } \ 0000000A 7047 BX LR ;; return \ ??Test_1: \ 0000000C ........ DC32 a Как видите, никакой ругани, делает все, как просилось. Я могу предположить, что ругань выглядит так: Цитата Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement D:\*****\loader.cpp 77 Но она означает вовсе не "не может проинициализировать", а "не определен порядок обращения к volatile-переменным". И вызывает его примерно такой код: Код int a; volatile int b; volatile int c; void Test() { a = b + c; } И это предупреждение совершенно справедливо: стандарт позволяет компилятору изменять порядок вычисления подвыражений. А поскольку одно из свойств volatile-переменных состоит в том, что чтение может изменять ее значение (а таким свойством обладают многие sfr-регистры), то изменение порядка чтения двух volatile-переменных может привести к неожиданным для вас результатам. Поэтому для разрешения неоднозначности надо разделить чтения точками последовательности, т.е. ";" или оператором "запятая", введя временную переменную как я сделал в примере выше. Но это лишь гадание.Если бы вы представили минимальный необходимый для воспроизведения ситуации код - вы бы получили более точный и быстрый ответ. Цитата(DenisIV @ Dec 26 2008, 00:14)  Варнинги достали (>100)  Поэтому бороться надо с их причиной, а не следствием.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 25 2008, 22:50
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Dec 26 2008, 01:26)  Это не лирика, это где-то у вас преднамеренно отключены предупреждения (Project->Options->C/C++ compiler->Diagnostics) Угу, и у тебя тоже  не все включено, ибо еще, если мне не изменяет склероз, должено быть что-то типа Еxpression is constant. Цитата(DenisIV @ Dec 26 2008, 00:19)  while(1) { .... } Вобще-то сие однозначно со всех точек зрения пишется так: Код for(;; ) { .... }
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 25 2008, 23:15
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(zltigo @ Dec 26 2008, 00:50)  Угу, и у тебя тоже  не все включено, ибо еще, если мне не изменяет склероз, должено быть что-то типа Еxpression is constant. Абижяешь, начальник! Я их никогда не отключаю. Нет предупреждения ни в С ни в С++ режиме. ИАР для ARM, 4.30 Цитата(zltigo @ Dec 26 2008, 00:50)  Вобще-то сие однозначно со всех точек зрения пишется так: Согласен, так и пишу. Но тут надо было повторить исходные условия эксперимента.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 26 2008, 08:07
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Dec 26 2008, 02:15)  Абижяешь, начальник! Я их никогда не отключаю. Нет предупреждения ни в С ни в С++ режиме. Я же не говорил про отключение я говорил про "не все включено"  . Ой, а что у меня это, если написать while(1) : Код IAR ARM ANSI C/C++ Compiler ..... D:\ARM_WORK\COMMON\LPC2000\console.c(356) : Remark[Pe236]: controlling expression is constant Просто в IAR по умолчанию ремарки отключены  надо включать, тем более, что под remark в IAR попадают и такие суровые приколы, как Remark[Pe193]: zero used for undefined preprocessing identifier
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 26 2008, 12:42
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(zltigo @ Dec 26 2008, 01:50)  Вобще-то сие однозначно со всех точек зрения пишется так: Код for(;; ) { .... } А есть разница?  Код while(1) { .... } По-моему нет. В справке к Hi-Tech C они предлагают для бесконечного цикла for(;;) { .... } При каком-то кол-ве циклов внутри цикла for{ for { for { for {}}}} компилятор вешается поэтому приходится комбинировать for... while... if... и т.д. В IAR пока не смотрел. Вроде таких проблем не было.
|
|
|
|
|
Dec 26 2008, 13:39
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(DenisIV @ Dec 26 2008, 15:42)  А есть разница?  Разумеется. Если for( ; ; ) есть прямое и безусловно однозначное указание компилятору изобразить вечный цикл, то while(1) есть указание крутиться и слушать пока рак на горе свистнет. Что не есть одно и то-же. Хотя сколь-нибудь приличный оптимизирующий компилятор знакомый с русским фольклером и анатомическим строением ракообразных  тоже сделает безусловный вечный цикл. Ну и, естественно, хороший компилятор при этом обязан предупредить - ты чего тут барин загадки загадываешь? Точно этого хотел, али опосля вчерашнего того..... Цитата(DenisIV @ Dec 26 2008, 15:42)  При каком-то кол-ве циклов внутри цикла for{ for { for { for {}}}} компилятор вешается поэтому приходится комбинировать for... while... if... и т.д. Опять  ужасы.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 26 2008, 16:26
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(zltigo @ Dec 26 2008, 16:39)  Разумеется. Если for( ; ; ) есть прямое и безусловно однозначное указание компилятору изобразить вечный цикл, то while(1) есть указание крутиться и слушать пока рак на горе свистнет. Что не есть одно и то-же. Хотя сколь-нибудь приличный оптимизирующий компилятор знакомый с русским фольклером и анатомическим строением ракообразных  тоже сделает безусловный вечный цикл. Ну и, естественно, хороший компилятор при этом обязан предупредить - ты чего тут барин загадки загадываешь? Точно этого хотел, али опосля вчерашнего того..... Опять  ужасы. Ну я бы так не сказал: если в for(;;) нет условия, это может быть ошибкой, а for(;1;) тоже, что и while(1) и раз уж так, то while() { .... } должно работать так же как и for(;;) ? Т.е. в for не надо вставлять условие ??? а в while надо ??? Правильным будет всегда с условием. Это точно не противоречит стандарту С. А то, что как вы сказали "оптимизирующий компилятор знакомый с русским фольклором" - это скорее исключение, а не правило. Поэтому и обидно...  Если я буду всем советовать for(;;) то это не будет правильно. Что for(;;) что while() - Варнинги обеспечены по любому. А хотелось бы писать правильно. И запись for(;1;) будет правильней.
|
|
|
|
|
Dec 26 2008, 16:41
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(DenisIV @ Dec 26 2008, 19:26)  Что for(;;) что while() - Варнинги обеспечены по любому.  нет. Для этого просто надо знать язык - по стандарту ВСЕ ТРИ expression у for() ОПЦИОНАЛЬНЫ. В отличии от while() у которого один, но ОБЯЗАТЕЛЬНЫЙ. При этом оговаривается, что отсутствующее второе выражение у for() заменяется ненулевой константой. Цитата А хотелось бы писать правильно. И запись for(;1;) будет правильней. Не, глупее  и при этом вменяемый компилятор обязан предупредить, как и в случае с while( 1 ) чем-нибудь типа 'controlling expression is constant'. Кстати, а почему 1, а не 666???  глупость, короче, если и писать глупости, то хоть без конкретики - while( TRUE )
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 26 2008, 23:10
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sergeeff @ Dec 26 2008, 23:02)  Как написано... Вы слишком много читаете, настолько много, что смысл прочитанного от Вас ускользает а в памяти остаются только культовые имена. Не найдете Вы в этой классической книге ни одого while( 1 ). А for( ; ; ) найдете, ибо автор 'C' отличался хорошим вкусом. А Ваша читата просто вырвана из другого, не связанного с организацией бесконечных циклов контекста. Цитата(sergeeff @ Dec 26 2008, 23:02)  А что такое TRUE? Общепринятое, максимально читабельное и соответствующее сущности значение.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 26 2008, 23:51
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(rezident @ Dec 27 2008, 02:34)  А не пора ли уже прекратить "религиозные" споры? Если результат компиляции одинаков Результат разный - в случае for( 1 ) приличными компиляторами выдается предупреждение, на которое можно, конечно, наплевать, что сделает компилятор при отключенной оптимизации - тоже на его совести. Можете считать это "религиозным" убеждением, наплевательское отношение к делу, равно, как и безграмотная писанина, мне не по душе. Впрочем в данном случае я смог высказаться полностью, более мне добавить нечего, а далее могущий понять да поймет - продолжать не буду.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 27 2008, 22:18
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(zltigo @ Dec 27 2008, 04:51)  в случае for( 1 ) приличными компиляторами выдается предупреждение, на которое можно, конечно, наплевать, что сделает компилятор при отключенной оптимизации - тоже на его совести. Хотя я и не имел в виду именно эту конструкцию, но и ее тоже проверил. В последних версиях IAR не выдает ни warning, ни remark ни на while(1), ни на for(;1;) . По-вашему фирма IAR "прогнулась" под привычки программистов? Как-то не соотносится это (желание "прогнуться") с введением той же MISRA C в их компиляторы, не находите?
|
|
|
|
|
Dec 27 2008, 22:38
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(rezident @ Dec 28 2008, 01:18)  В последних версиях IAR не выдает ни warning, ни remark ни на while(1), ни на for(;1;) . Последние это какие? Ремарки включите. Код 573 574 for(; 1; ) ^ Remark[Pe236]: controlling expression is constant 575 { 576 led_process( led_cnt++ ); Цитата По-вашему фирма IAR "прогнулась" под привычки программистов? Как-то не соотносится это (желание "прогнуться") с введением той же MISRA C в их компиляторы, не находите? Не нахожу. MISRA присутствует с незапамятных времен и с "успехом" ругается практически на все  , что написано. И соответственно доводит до полного абсурда систему варнингов.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 28 2008, 01:49
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Да надо плюнуть на все эти глупости, написать: Код label1: ... ... goto label1; и будет вам счастье! Никаких warning'ов, корректно и, скорее всего, максимально быстрый цикл. Правда, не структурненько, но и хрен бы с ними, этими условностями. После можно расслабиться и спокойно готовиться к празднованию Нового года. Чего всем и желаю.
|
|
|
|
|
Dec 28 2008, 08:44
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Думаю, что пишу в тему. История такая (WinAVR): Все знают, что манипуляции с main() - дело неприличное. В общем, заметил я глупости, которые делает последний WinAVR - лишние сохранения/восстановления регистров, после чего стал везде писать Код int main (void) __attribute__((naked)); int main(void) { //итд итп } Худеет где-то на 24 и более байта. Т.е. компилер не понимат, что с main() не надо так обращаться, как со всеми прочими функциями...
|
|
|
|
|
Dec 28 2008, 08:55
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(zltigo @ Dec 28 2008, 13:37)  Если планомерно убирают, то тем хуже  . Причины, по которым считаю отсутствие предупреждений неправильным, изложил ранее. Косвенной причиной промолчать может служить и реальная необходимость в такой конструкции do{...}while(FALSE) Хотя и в этом случае лично я предпочел-бы "официальный трюк" для такого действа вместо молчаливой оптмизации. Возможно, это и есть "официальный трюк"? В смысле, может быть, ремарки не выдаются только на несколько фиксированных конструкций? Rezident, не могли бы Вы проверить что-нибудь позаковыристей? Типа Код unsigned a; while (a >= 0){ ... } , или что-то наподобие?
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Dec 28 2008, 09:00
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(_Pasha @ Dec 28 2008, 11:44)  Т.е. компилер не понимат, что с main() не надо так обращаться, как со всеми прочими функциями...  Ничего не мешает, если сие необходимо сделать из main() return и вернувшись в startup заняться другими делами, например, выполнением supermain().... Посему в качестве "навязчивого сервиса" делать main() особой совершенно не верно. Ручками - ручками пожалуйста.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 28 2008, 11:56
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(_Pasha @ Dec 28 2008, 10:44)  после чего стал везде писать Код int main (void) __attribute__((naked)); А это не вам aesok тут на форуме объяснял, что naked, кроме сохранения ненужных регистров, еще и выделение стека под локальные переменные отбрасывает? Т.е. делать так нельзя, для main() и подобных функций есть атрибут OS_task.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 30 2008, 20:19
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Подскажите ещё плиз: У меня на асме для оптимизации была такая конструкция подпрограммы с несколькими точками входа. Например: здоровенная подпрограмма, которой передаётся байт для обработки (~100 вызовов) и вызов этой же подпрограммы с вполне конкретным значением (3-4 варианта по ~40 вызовов) Как можно это применить в С? Как программист C я понимаю, что вызов функции, которая будет содержать константу для этой функции подойдёт, но для PIC (8 уровней стека  ) не прокатит... Есть какая-нибудь альтернатива? Дополнительный параметр в функции передавать не хочу- в экономии смысла не будет, скорее наоборот. Глобальная переменная-как вариант, но не выход... Есть возможность вызвать функцию с какой-либо метки внутри, или это совсем глупо? Или есть варианты? Или это должен делать и считать оптимизатор?
Сообщение отредактировал DenisIV - Dec 30 2008, 20:38
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|