Pjotar 0 30 апреля, 2009 Опубликовано 30 апреля, 2009 (изменено) · Жалоба Вот такой вот код, inline uint32_t crc32_add( uint32_t crc, uint8_t byte ) { crc ^= byte; for (uint8_t i=0; i<8; i++) { if (crc & 1) { crc = (crc>>1) ^ CRC32_POLYNOME; } else { crc >>= 1; } } return crc; } скомпилирован для двух платформ: BorlandCC для ПК и GCC для AVR.... На разных платформах разные результаты выполнения. Какими словами уточнить код, чтобы компиляторы наконец договорились? Ещё два момента: я пока не знаю, кто из них на данный момент правильно работает. В борланде подключен \\avr\\include\\inttypes.h из WinAVR. Спасибо :) Изменено 30 апреля, 2009 пользователем Злодей Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
FormatCft 0 30 апреля, 2009 Опубликовано 30 апреля, 2009 · Жалоба Вот такой вот код, inline uint32_t crc32_add( uint32_t crc, uint8_t byte ) { crc ^= byte; for (uint8_t i=0; i<8; i++) { if (crc & 1) { crc = (crc>>1) ^ CRC32_POLYNOME; } else { crc >>= 1; } } return crc; } скомпилирован для двух платформ: BorlandCC для ПК и GCC для AVR.... На разных платформах разные результаты выполнения. Какими словами уточнить код, чтобы компиляторы наконец договорились? Я пока не знаю, кто из них на данный момент правильно работает. В борланде подключен \\avr\\include\\inttypes.h из WinAVR. Спасибо :) Можно пошагово в отладчике пройтись и узнать где начинает отличаться. Действия простые и проблем быть не должно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 30 апреля, 2009 Опубликовано 30 апреля, 2009 · Жалоба А результат всегда одинаковый в обоих случаях? { crc ^= byte; Вот, например, неочевидно, чему был равен crc до этой операции Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pjotar 0 30 апреля, 2009 Опубликовано 30 апреля, 2009 (изменено) · Жалоба А результат всегда одинаковый в обоих случаях? { crc ^= byte; Вот, например, неочевидно, чему был равен crc до этой операции Здесь всё в порядке. crc - аргумент фунции. Изменено 30 апреля, 2009 пользователем Злодей Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 30 апреля, 2009 Опубликовано 30 апреля, 2009 · Жалоба Здесь всё в порядке. crc - аргумент фунции. А, ну да... чё-то я парю... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pjotar 0 30 апреля, 2009 Опубликовано 30 апреля, 2009 (изменено) · Жалоба Вчера пытался компилировать в GCC без оптимизации так он отказывался... Ставил везде-везде volatile - не помогало. В AVR Studio видно, что осталось от кода: uintX_t crc32_add( uintX_t crc, uint8_t byte ) { crc ^= byte; uint8_t i = 8; do { crc >>= 1; } while(--i); return crc; } Вот этот кусок отсутствует полностью. Типа младший бит всегда 0 :w00t: Нашлиииии! А как починить? if (crc & 1) { crc = (crc>>1) ^ CRC32_POLYNOME; } Спасибо FormatCft, направил меня на путь истинный :) Изменено 30 апреля, 2009 пользователем Злодей Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 30 апреля, 2009 Опубликовано 30 апреля, 2009 · Жалоба Вчера пытался компилировать в GCC без оптимизации так он отказывался... Не может такого быть. А он мотивировал? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 30 апреля, 2009 Опубликовано 30 апреля, 2009 · Жалоба Вот этот кусок отсутствует полностью. Йа Станиславский :) Вы точно ходили, жмя F11 или смотрели *.lss или еще какую вредную шнягу ? Objdump доведет до коровьего бешенства. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pjotar 0 30 апреля, 2009 Опубликовано 30 апреля, 2009 · Жалоба Помогите, пожалуйста исправить ошибку "left shift count >= width of type" uint32_t crc; crc <<= 1U; Вот такую сам вылечил uint32_t crc; //if (crc & ( 1 << 31 ) ) //ошибка if (crc & ((uint32_t)1 << 31) ) Йа Станиславский :) Вы точно ходили, жмя F11 или смотрели *.lss или еще какую вредную шнягу ? Objdump доведет до коровьего бешенства. Так и есть, спал 2 часа, потом стоматолог дррррр, а теперь ещё и дизассембить. Извините оффтоп. Что же делать "warning: left shift count >= width" crc <<= 1U; //uint32_t crc; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 30 апреля, 2009 Опубликовано 30 апреля, 2009 · Жалоба Вот такую сам вылечил Не-не-не-не.. uint32_t crc; if (crc & (1UL << 31) ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pjotar 0 30 апреля, 2009 Опубликовано 30 апреля, 2009 · Жалоба Помогите, пожалуйста исправить ошибку "left shift count >= width of type" uint32_t crc; crc <<= 1U; Простите, это уже шиза :) В следующей строчке в константе прятался макрос, там ошибка на которую указал Не-не-не-не.. uint32_t crc; if (crc & (1UL << 31) ) Спасибо! Я теперь понял зачем нужны U и L :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 30 апреля, 2009 Опубликовано 30 апреля, 2009 · Жалоба Спасибо! Я теперь понял зачем нужны U и L :) Пожалуйста. Тут с похожими граблями недавно пробегал кто-то, если указать (uint32_t)(1<<32), то он вначале 16-разрядную единицу сдвинет на 32 влево, а потом приведет к 32-разрядному. По этой причине я разлюбил пользоваться макросами типа _BV() - из-за скрытия наглядности Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 30 апреля, 2009 Опубликовано 30 апреля, 2009 · Жалоба Вот такой вот код, ..... скомпилирован для двух платформ: BorlandCC для ПК и GCC для AVR.... На разных платформах разные результаты выполнения. Какими словами уточнить код, чтобы компиляторы наконец договорились? В коде я никакого криминала не усмотрел... Ещё два момента: я пока не знаю, кто из них на данный момент правильно работает. В борланде подключен \\avr\\include\\inttypes.h из WinAVR.=8-( ) А почему используется файл от другого компилятора? За размерность типов отвечает компилятор, поэтому файл stdint.h (в котором определены типы uintXX_t и который подключается из файла inttypes.h) должен браться только из комплекта компилятора, которым осуществляется компиляция. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mdmitry 0 30 апреля, 2009 Опубликовано 30 апреля, 2009 · Жалоба Часто необходимо приведение типа внутри кода (это CRC8): char wk_crc8_block(const char *datablock, const unsigned int count_byte) { register unsigned int count; char crc1, ch; crc1 = (char)CRC_WAKE_INIT; for(count = 0; count < count_byte; count++) { ch = (char)datablock[count]; Do_Crc8(ch, &crc1); } crc1 = (char)crc1; return(crc1); } void Do_Crc8(char b, char *crc) { int i; for (i = 0; i < 8; i++) { if (((b ^ *crc) & 1) != 0) *crc = (char)(((*crc ^ 0x18) >> 1) | 0x80); else *crc = (char)((*crc >> 1) & ~0x80); b = (char)(b >> 1); } } Без явного приведения типа к (char) для AVR -все в порядке, а на PC и freescale MC56F8346 полный бред. Компилятор любит использовать размер данные "родной" для платформы (AVR - 8 бит, Freescale - 16, PC - 32). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
forever failure 0 30 апреля, 2009 Опубликовано 30 апреля, 2009 · Жалоба Часто необходимо приведение типа внутри кода (это CRC8): char wk_crc8_block(const char *datablock, const unsigned int count_byte) { register unsigned int count; char crc1, ch; crc1 = (char)CRC_WAKE_INIT; for(count = 0; count < count_byte; count++) { ch = (char)datablock[count]; Do_Crc8(ch, &crc1); } crc1 = (char)crc1; return(crc1); } void Do_Crc8(char b, char *crc) { int i; for (i = 0; i < 8; i++) { if (((b ^ *crc) & 1) != 0) *crc = (char)(((*crc ^ 0x18) >> 1) | 0x80); else *crc = (char)((*crc >> 1) & ~0x80); b = (char)(b >> 1); } } Без явного приведения типа к (char) для AVR -все в порядке, а на PC и freescale MC56F8346 полный бред. Компилятор любит использовать размер данные "родной" для платформы (AVR - 8 бит, Freescale - 16, PC - 32). Тут проблема может быть в другом, и явное приведение типа вовсе ни при чём. По стандарту не оговаривается чётко, должен быть беззнаковым тип char или иметь знак. Поэтому поведение такого кода может изменятся даже для одного и того же целевого процессора, в зависимости от ключей компиляции, а уж при переходе от одной платформы к другой - и подавно. Вот и получается, что для AVR char может быть беззнаковым - и всё в порядке, а на PC и Freescale char имеет знак - и получается полный бред. В таких случаях и надо использовать стандартный восьмибитный беззнаковый тип - uint8_t (который в большинстве случаев, но опять же не всегда - unsigned char). ЗЫ. А stdint.h надо брать тот, который идёт с компилятором, а не из чужой среды, т. е. для борланда - борландский, для AVR - avrовский. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться