|
Ошибка IAR или чтото еще? |
|
|
|
 |
Ответов
|
Dec 18 2006, 19:38
|

Гуру
     
Группа: Свой
Сообщений: 3 041
Регистрация: 10-01-05
Из: Москва
Пользователь №: 1 874

|
Ответ прост. До тех пор, пока результат вычисления всего целочисленного выражения не отличается от стандартного способа вычисления с учетом того, что при переполнении промежуточных результатов возможно undefined поведение, компилятор может делать все, что угодно. Но только пока не отличается. Более того, важен даже не результат вычисления одного выражения, а последовательность записи значений в volatile переменные и вызовов системных функций. Все оптимизации программы, которые сохраняют запись в volatile переменные и ызовы системных функций - законные, все, которые приводят к изменению внешнего поведения программы - незаконны.
--------------------
Пишите в личку.
|
|
|
|
|
Dec 18 2006, 20:31
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Oldring @ Dec 18 2006, 19:38)  Ответ прост. До тех пор, пока результат вычисления всего целочисленного выражения не отличается от стандартного способа вычисления с учетом того, что при переполнении промежуточных результатов возможно undefined поведение, компилятор может делать все, что угодно. Но только пока не отличается. Более того, важен даже не результат вычисления одного выражения, а последовательность записи значений в volatile переменные и вызовов системных функций. Все оптимизации программы, которые сохраняют запись в volatile переменные и ызовы системных функций - законные, все, которые приводят к изменению внешнего поведения программы - незаконны. Меня "правильность" компилятора мало интересует, я не д-р Туамосец. Я рассматриваю правильность как максимально близкий результат к результату при перемножении в столбик И получается такая незадача, что правильность зависит от значения переменных. int a,b,c; a*b/c при a=100, b=100, c=3 правильно будет (a*  /c, а при a=1000, b=1000, c=100 правильно будет a*(b/c). Поэтому весь этот дискуссион не имеет смысла, тем более что автор не указал даже с какими числами он работал и предусмотрен ли запас по диапазону. Потому и залег на дно, видимо, предоставив нам возможность друг друга за чубы тягать Цитата(Oldring @ Dec 18 2006, 20:08)  3. Нет. Компилятор обязан сделать чтобы снаружи выглядело как ему написали в любом случае. Хм... Например, оптимизатор IAR самостоятельно заменяет switch (a) {case ....} на vector[a] и создает массив функций при большом числе a. Такое решение выглядит, как написали, или не выглядит?
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Dec 18 2006, 20:43
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(Dog Pawlowa @ Dec 19 2006, 00:31)  И получается такая незадача, что правильность зависит от значения переменных. int a,b,c; a*b/c при a=100, b=100, c=3 правильно будет (a*  /c, а при a=1000, b=1000, c=100 правильно будет a*(b/c). Поэтому весь этот дискуссион не имеет смысла, тем более что автор не указал даже с какими числами он работал и предусмотрен ли запас по диапазону. Потому и залег на дно, видимо, предоставив нам возможность друг друга за чубы тягать  Вы специально со скобками дуру гоните, али как? Выражаясь Вашими формулами вопрос задаем так - ПОЧЕМУ: Global_Value = a * b / c отличается от Local_Value = a * b / c; Скобки и привидения к типам в обоих равенствах можете расставить по собственному усмотрению и вкусу, НО одинаково Цитата(Dog Pawlowa @ Dec 19 2006, 00:31)  Цитата(Oldring @ Dec 18 2006, 20:08)  3. Нет. Компилятор обязан сделать чтобы снаружи выглядело как ему написали в любом случае.
Хм... Например, оптимизатор IAR самостоятельно заменяет switch (a) {case ....} на vector[a] и создает массив функций при большом числе a. Такое решение выглядит, как написали, или не выглядит? Как раз подходит под то, что говорит Oldring - снаружи функции и со switch (a) {case ....} и с vector[a] будет выглядеть одинаково, здесь же мы наблюдаем "не одинаково"
--------------------
|
|
|
|
|
Dec 19 2006, 09:49
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(prottoss @ Dec 18 2006, 20:43)  Вы специально со скобками дуру гоните, али как? Выражаясь Вашими формулами вопрос задаем так - ПОЧЕМУ: Global_Value = a * b / c отличается от Local_Value = a * b / c; Скобки и привидения к типам в обоих равенствах можете расставить по собственному усмотрению и вкусу, НО одинаково Дуру? Отчасти А на конкретный вопрос - конкретный ответ : Да, сравнивать Global_Value = a * b / c и Local_Value = a * b / c при int a,b,c считаю некорректным. Но можно сравнивать Global_Value = a * (b / c) и Local_Value = a *( b / c) Или Global_Value = (long) a * (long) b / c и Local_Value = (long)a *(long) b / c, а еще лучше Global_Value = ((long) a * (long) b ) / c и Local_Value = ((long)a *(long) b ) / c И только после этого может появиться предположение об "ошибке". У меня один и тот же проект постоянно портируется с MS VC на IAR AVR и обратно, да, было пару выбрыков у ИАРа, но в целом это вполне нормальный инструмент. За приемлемую цену Все, пока автор не появится - ни строчки.
Сообщение отредактировал Dog Pawlowa - Dec 19 2006, 09:54
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Dec 19 2006, 11:57
|
Местный
  
Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526

|
[/quote] Дуру? Отчасти А на конкретный вопрос - конкретный ответ : Да, сравнивать Global_Value = a * b / c и Local_Value = a * b / c при int a,b,c считаю некорректным. Но можно сравнивать Global_Value = a * (b / c) и Local_Value = a *( b / c) Или Global_Value = (long) a * (long) b / c и Local_Value = (long)a *(long) b / c, а еще лучше Global_Value = ((long) a * (long) b ) / c и Local_Value = ((long)a *(long) b ) / c И только после этого может появиться предположение об "ошибке". У меня один и тот же проект постоянно портируется с MS VC на IAR AVR и обратно, да, было пару выбрыков у ИАРа, но в целом это вполне нормальный инструмент. За приемлемую цену Все, пока автор не появится - ни строчки. [/quote] Вот и автор. Итак, что касается значения переменных. В приведенном случае: data_temp_struct.temp = INJ_time * data_temp_struct.FREQ * PRODUCTIVITY / 20000; long int INJ_time = от 74 000 до 75 000 unsigned int data_temp_struct.FREQ = 1000 (задается в процессе эксперимента) PRODUCTIVITY = 5 (в данном случае) long int Local_Value temp = INJ_time * data_temp_struct.FREQ * PRODUCTIVITY / 20000; где long int Local_Value размещена в регистрах в результате дает непонятное случайное число заменив переменную temp на data_temp_struct.temp я добился того, что она теперь размещена в памяти. При этом все вычисления пошли верно. Теперь о свертывании констант - как вы можете видеть, PRODUCTIVITY (=5)/ 20000 корректно никак свернуто быть не может (при данных значениях) Был проделан сл эксперимент - формула была упрощена до вида: long int Local_Value temp = INJ_time * PRODUCTIVITY; И только... Результат был неверным! Только размещение в памяти результирующей переменной дало эффект!!! Т.о. у меня есть 2 подозрения - 1. глюк компиллятора 2. Коллизия с распределением памяти. Возможно стек возвратов, возможно стек данных. Многие глюки у меня решались именно изменением этих параметров. Правда, в данном случае мне не удалось подобрать ничего правильного. Дело в том, что проект очень большой порядка 10 000 строк. Большой расход памяти, задействованы почти все мыслимые и немыслимые аппаратные ресурсы и прерывания. Возможно, компиллятор столкнулся с какими то внутренними проблемами при обработке такого сложного проекта. Кстати, оптимизацию я полностью отключал. На это грешить не приходится. Вот такие дела!
|
|
|
|
|
Dec 19 2006, 15:15
|
Местный
  
Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526

|
Цитата(Oldring @ Dec 19 2006, 15:44)  Цитата(Sergio66 @ Dec 19 2006, 11:57)  Результат был неверным! Только размещение в памяти результирующей переменной дало эффект!!!
Так сразу после вычисленя выражения в регистрах результат правильный? Ошибки компилятора, конечно, встречаются - но в 90% случаев подозрения на ошибки компилятора не оправдываются, оказываясь ошибками программиста. Поэтому утверждение про ошибку компилятора требуют более серьезных аргументов, чем "написал так - не работает, написал иначе - работает". Да нет же! Пока я не переразместил переменную, все считалось неверно. И в регистрах был неверный результат.
|
|
|
|
|
Dec 19 2006, 19:10
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Sergio66 @ Dec 19 2006, 15:15)  Да нет же! Пока я не переразместил переменную, все считалось неверно. И в регистрах был неверный результат. Тот самый случай, когда лучше один раз увидеть, чем сто раз услышать. А еще лучше совсем не видеть :-) Я вот недавно буфер для sprintf малый сделал, и пол-дня искал причину затирания переменной, все ошибки в компиляторе искал и стек считал... Нет?
--------------------
Уходя, оставьте свет...
|
|
|
|
Сообщений в этой теме
Sergio66 Ошибка IAR или чтото еще? Dec 18 2006, 12:47 aesok Показывайте код. Dec 18 2006, 13:06 Sergio66 Цитата(aesok @ Dec 18 2006, 13:06) Показы... Dec 18 2006, 13:15  _Bill Цитата(Sergio66 @ Dec 18 2006, 13:15) Вот... Dec 18 2006, 14:48   Sergio66 Цитата(_Bill @ Dec 18 2006, 14:48) Цитата... Dec 18 2006, 15:01    aesok Опишите проблемму полностью:
Как переменые и стру... Dec 18 2006, 15:18    Dog Pawlowa Цитата(Sergio66 @ Dec 18 2006, 15:01) А ч... Dec 18 2006, 15:28     Sergio66 Цитата(Dog Pawlowa @ Dec 18 2006, 15:28) ... Dec 18 2006, 15:44     prottoss Цитата(Dog Pawlowa @ Dec 18 2006, 19:28) ... Dec 18 2006, 15:45      Dog Pawlowa Цитата(prottoss @ Dec 18 2006, 15:45) Ска... Dec 18 2006, 16:46       prottoss Цитата(Dog Pawlowa @ Dec 18 2006, 20:46) ... Dec 18 2006, 17:08        Dog Pawlowa Цитата(prottoss @ Dec 18 2006, 17:08) Цит... Dec 18 2006, 18:48         Oldring Цитата(Dog Pawlowa @ Dec 18 2006, 18:48) ... Dec 18 2006, 19:08          singlskv Цитата(Oldring @ Dec 18 2006, 19:08) Дело... Dec 18 2006, 19:31          _Bill Цитата(Oldring @ Dec 18 2006, 19:08) Цита... Dec 20 2006, 15:06           Oldring Цитата(_Bill @ Dec 20 2006, 15:06) Код b ... Dec 20 2006, 16:30   Oldring Цитата(_Bill @ Dec 18 2006, 14:48) Ну, та... Dec 18 2006, 17:27 singlskv Цитата(Sergio66 @ Dec 18 2006, 12:47) Сто... Dec 18 2006, 16:11 singlskv Цитата(Oldring @ Dec 18 2006, 19:38) Отве... Dec 18 2006, 19:53  Oldring Цитата(Dog Pawlowa @ Dec 18 2006, 20:23) ... Dec 18 2006, 20:37   Oldring Цитата(prottoss @ Dec 18 2006, 20:43) Выр... Dec 18 2006, 21:14   singlskv Цитата(prottoss @ Dec 18 2006, 20:43) Выр... Dec 18 2006, 21:18     Dog Pawlowa Цитата(Sergio66 @ Dec 19 2006, 11:57) Был... Dec 19 2006, 19:24 Oldring Не совсем.
1. Включение оптимизации самой по себе... Dec 18 2006, 20:08 GDI Была у меня похожая проблема, правда, у меня порти... Dec 19 2006, 13:32 singlskv автар
продемонстрируйте свое искуство, так сказать... Dec 19 2006, 19:18 Oldring int расширяется до long до умножения. Потом должна... Dec 19 2006, 19:50 Sergio66 Цитата(Oldring @ Dec 19 2006, 19:50) int ... Dec 20 2006, 13:33  Oldring Цитата(Sergio66 @ Dec 20 2006, 13:33) 1. ... Dec 20 2006, 14:13 Serg79 Sergio66 Ты сдесь воду то не баламуть а приведи но... Dec 20 2006, 15:22 prottoss Пока Sergio66 молчит, задам я свой вопрос, потому ... Dec 20 2006, 16:15 prottoss Мда... Умные речи о значимости скобок не помогли..... Dec 20 2006, 17:32 Dog Pawlowa Цитата(prottoss @ Dec 20 2006, 17:32) Мда... Dec 20 2006, 17:54  prottoss Цитата(Dog Pawlowa @ Dec 20 2006, 21:54) ... Dec 20 2006, 18:05   singlskv Цитата(prottoss @ Dec 20 2006, 18:05) Я с... Dec 20 2006, 19:29    prottoss Цитата(singlskv @ Dec 20 2006, 23:29) Pro... Dec 20 2006, 20:04     Oldring Цитата(prottoss @ Dec 20 2006, 20:04) В п... Dec 20 2006, 20:09      prottoss Цитата(Oldring @ Dec 21 2006, 00:09) Ключ... Dec 20 2006, 20:23 Oldring Чтобы не напрягать попусту наши извилины скомпилир... Dec 20 2006, 18:57 prottoss Цитата(Oldring @ Dec 20 2006, 22:57) Чтоб... Dec 20 2006, 19:12 Oldring Замечательно, где еще прописывается значение Pulse... Dec 20 2006, 19:19 prottoss Цитата(Oldring @ Dec 20 2006, 23:19) Заме... Dec 20 2006, 19:26 Oldring Я конечно имел в виду дизассемблер, в котором изме... Dec 20 2006, 19:28 Oldring Да, не забудьте убедиться, что функция после преры... Dec 20 2006, 19:34 Oldring Пожалуйста, приведите два варианта кода отдельно -... Dec 20 2006, 20:28 prottoss Цитата(Oldring @ Dec 21 2006, 00:28) Пожа... Dec 20 2006, 20:43 Oldring Ну так а когда в нерабочем варианте вызывается фун... Dec 20 2006, 20:45 prottoss Цитата(Oldring @ Dec 21 2006, 00:45) Ну т... Dec 20 2006, 20:53 Oldring Только этот вариант все равно не должен компилиров... Dec 20 2006, 21:02 prottoss Цитата(Oldring @ Dec 21 2006, 01:02) Толь... Dec 21 2006, 17:09  Dog Pawlowa Цитата(prottoss @ Dec 21 2006, 17:09) Все... Dec 21 2006, 17:39   prottoss Цитата(Dog Pawlowa @ Dec 21 2006, 21:39) ... Dec 21 2006, 18:04    Dog Pawlowa Цитата(prottoss @ Dec 21 2006, 18:04) А в... Dec 21 2006, 18:44     prottoss Цитата(Dog Pawlowa @ Dec 21 2006, 22:44) ... Dec 21 2006, 19:02      defunct Цитата(prottoss @ Dec 21 2006, 19:02) Да ... Dec 21 2006, 20:33       Serg79 Цитата(defunct @ Dec 21 2006, 20:33) Насч... Dec 22 2006, 13:29       prottoss Цитата(defunct @ Dec 22 2006, 00:33) Цита... Dec 22 2006, 14:57        defunct Цитата(prottoss @ Dec 22 2006, 14:57) Что... Dec 22 2006, 16:20         Wild007 2 defunct
ЦитатаВы ставите в противовес JTAG... Dec 22 2006, 17:02         prottoss Цитата(defunct @ Dec 22 2006, 20:20) Цита... Dec 22 2006, 17:05          defunct Цитата(prottoss @ Dec 22 2006, 17:05) Чит... Dec 22 2006, 17:25  singlskv Цитата(prottoss @ Dec 21 2006, 17:09) Уве... Dec 21 2006, 19:47 WHALE [/quote]
В начале программы забивайте весь отведен... Dec 21 2006, 22:05 singlskv Цитата(WHALE @ Dec 21 2006, 22:05) Цитата... Dec 21 2006, 22:14
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|