|
|
  |
Лучшее - враг хорошего?, Глюки при оптимизации компилятора KEIL |
|
|
|
May 31 2012, 01:12
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(vlad_new @ May 31 2012, 03:42)  Если массив объявлен внутрии фунции как char mas[100], и при попытке вызвать из этой ф-ции другую с передачей адреса этого массива, иногда получается дребедень. При оптимизации компилятор небольшие массивы помещает в стек и передать адрес такого массива почему то не всегда выходит. Так что все локальные массивы ( от греха подальше ) объявляю как static char mas[100]. Вот так объявляете: Код void Func() { static char mas[100]; // код } ? Или так: Код static char mas[100]; void Func() {
// код } ? Цитата(vlad_new @ May 31 2012, 03:42)  К тому же чревато, что где то, стека может не хватить. Или ОЗУ не хватит. Цитата(vlad_new @ May 31 2012, 03:42)  А вообще мне тут советовали всегда заводить указатели на массивы чтоб не было проблемм с оптимизатором. Это ещё зачем? Да к тому же всегда? Где можно посмотреть на тот совет? Цитата(vlad_new @ May 31 2012, 03:42)  Я попробывал и мне понравился такой стиль. Зря...
|
|
|
|
|
May 31 2012, 08:50
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(vlad_new @ May 31 2012, 02:42)  Я вот еще чего вспомнил. Если массив объявлен внутрии фунции как char mas[100], и при попытке вызвать из этой ф-ции другую с передачей адреса этого массива, иногда получается дребедень. [...] Так что все локальные массивы ( от греха подальше ) объявляю как static char mas[100]. Я выше также написал, что у меня есть подозрения на локальные массивы. Однако делать временные внутрифункциональные массивы (и переменные вообще) статическими, а значит - перманентными в памяти, - не выход и не стиль. Более того, о реентерабельности таких функций можно сразу забыть. Цитата(Albun @ May 30 2012, 20:44)  Я не сохранял регистр R12, а как оказалось компилятор этот регистр тоже использует как регистр общего назначения, А что такое "ассемблерный код"?  .
Сообщение отредактировал KnightIgor - May 31 2012, 08:46
|
|
|
|
|
May 31 2012, 11:53
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(RabidRabbit @ May 31 2012, 12:39)  А оно там при -O0 переменные само не инициализирует? В коде я не полагаюсь на значения НЕинициализированных переменных, и напротив - инициализирую их, если необходимо. Не думаю, что компилятор "забывает" предписаную мной инициализацию на высоких уровнях оптимизации. Как уже говорилось, ошибка (которую я уже и не могу "восстановить") была частой, но не регулярной, чтобы можно было бы ее стабильно репродуцировать и отследить.
|
|
|
|
|
May 31 2012, 12:20
|
Местный
  
Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127

|
Цитата Вот так объявляете: Код void Func() { static char mas[100]; // код } Да. Цитата Или ОЗУ не хватит. Странный вопрос. Вы имели ввиду что стек - та же ОЗУ. Типа если не хватит того, то и не хватит другого? Цитата Зря... Зря не зря, но проблеммы с оптимизатором действительно исчезли. Да и указатели компелятор все равно создаст. Такая уж система команд у ARM. Нет у него прямого чтения/записи только косвенные. Так что код получается одинаковый с указателем или без. Цитата А оно там при -O0 переменные само не инициализирует? Если галка стоит использования микролиб (use microLib), то все будет инициализироваться должным образом. И к (-O0) оптимизации это не имеет оношения. Цитата В коде я не полагаюсь на значения НЕинициализированных переменных, и напротив - инициализирую их, если необходимо. Я раньше тоже так делал. А сейчас сразу задаю значение при объявлении. У KEIL-а с этим все нормалек. Тут ведь просто вопрос доверия компелятору.
Сообщение отредактировал vlad_new - May 31 2012, 12:41
|
|
|
|
|
May 31 2012, 12:40
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(vlad_new @ May 31 2012, 15:20)  Да. Странный вопрос. Если вы имели ввиду что стек - та же ОЗУ. Типа если не хватит того, то и не хватит другого? Нет. Я о другом: создавая массив static unsigned char mas[100] вы создаёте массив который существует всегда, по сути глобальный объект, но называется он - локальная статическая переменная, но память под него ушла. Цитата(vlad_new @ May 31 2012, 15:20)  Зря не зря, но проблеммы с оптимизатором действительно исчезли. В этот раз повезло. Цитата(vlad_new @ May 31 2012, 15:20)  Да и указатели компелятор все равно создаст. Так что код получается одинаковый с указателем или без. Вы ещё и какие-то указатели создаёте? Зачем? Раз компилятор "все равно создаст", то давайте их продублируем. Цитата(vlad_new @ May 31 2012, 15:20)  Такая уж система команд у ARM. Нет у него прямого чтения/записи только косвенные. Так что код получается одинаковый с указателем или без. Система команд у АРМ не той системы наверное. Понятно.
|
|
|
|
|
May 31 2012, 13:02
|
Местный
  
Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127

|
Цитата Нет. Я о другом: создавая массив static unsigned char mas[100] вы создаёте массив который существует всегда Ну да. А мне не все равно, если памяти и скорости хватает. Зато не надо потом целый день в отладчике сидеть и искать где оптимизатор опять что то натворил. Цитата Вы ещё и какие-то указатели создаёте? Зачем? Раз компилятор "все равно создаст", то давайте их продублируем. Самое сиешное, что вы абсолютно правы. И все таки разница есть. При оптимизации компилятор руководствуется константными значениями и может натворить что угодно, а если мы явно объявили указатель на массив, то вот хрен ему. Массив он уже не тронит. К тому же в больших проэктах, а тем более с чужими модулями и библиотеками, с указателями на массивы действительно удобнее работать. Ну опять же сколько нас - столько и мнений.
|
|
|
|
|
May 31 2012, 13:41
|
Местный
  
Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127

|
Цитата Но что там оптимизатор может натворить? А Вы его и спросите. К примеру sprintf(mas,"бла...бла", tmp); при объявленном локальном массиве char mas[10] и включенном оптимизаторе O1 просто не заработал. И передача адреса массива в другую функцию send(char *mas) то же не работало. Помог static.
Сообщение отредактировал vlad_new - May 31 2012, 13:49
|
|
|
|
|
May 31 2012, 13:50
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(vlad_new @ May 31 2012, 16:41)  А Вы его и спросите. Спросишь его ... он же памятник...Цитата(vlad_new @ May 31 2012, 16:41)  К примеру sprintf(mas,"бла...бла", tmp); при объявленном локальном массиве char mas[10] и включенном оптимизаторе O1 просто не заработал. И передача адреса массива в другую функцию send(mas) то же не работало. Ужасы какие-то... Вообще оптимизацией не воспользуешься, если оно так. Не верю: проблема где-то в другом месте.
|
|
|
|
|
May 31 2012, 13:59
|
Местный
  
Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127

|
Цитата Вообще оптимизацией не воспользуешься, если оно так. Да, но в KEIL-е без оптимизаиора нельзя. Как тут кто то сказал: "Без оптимизатора в KEIL-е на окно дизассемблера без слез не взглянеш." Да и скрость сразу в 2 раза ниже. Цитата Не верю: проблема где-то в другом месте. А мне какой прок придумывать? Мне KEIL всеравно нравится.
|
|
|
|
|
May 31 2012, 14:09
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(vlad_new @ May 31 2012, 16:59)  Да, но в KEIL-е без оптимизаиора нельзя. Как тут кто то сказал: "Без оптимизатора в KEIL-е на окно дизассемблера без слез не взглянеш." Да и скрость сразу в 2 раза ниже. На то она и оптимизация чтобы быстрей работать. Цитата(vlad_new @ May 31 2012, 16:59)  А мне какой прок придумывать? Я не говорю что придумываете. Цитата(vlad_new @ May 31 2012, 16:59)  Мне KEIL всеравно нравится. Всё равно его не брошу потому что он хороший... Чем может нравиться при таких косяках?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|