onic777 0 21 июля Опубликовано 21 июля · Жалоба Добрый день, Уважаемые коллеги! Я работаю в среде Arm Keil C v.5.23. Пишу FW для EFM32GG380 от Silicon Laboratories. Собственно вопрос: Имеется бибмлиотечная функция void LongToBytes (long LG, char* BYTES, byte Index) { byte i; for (i=0;i<4;i++) { BYTES[Index+i] = (*((unsigned char *)&(LG)+i)); } } В тесте программы используется массив байтов, объявленый как byte PID_CODE[4]; раннее uint8_t объявлен как byte Библиотечная функция вызывается как LongToBytes (ADDRESS,PID_CODE,0); При компиляции выдается warning: #223-D: function "LongToBytes" declared implicitly Что не так с вызовом? В этой же программе имеется ряд похожих функций, вызываемых также... Никаких предупреждений не наблюдается... Regards, Onic777 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 21 июля Опубликовано 21 июля · Жалоба Где-то выше точки вызова в глобальном пространстве (например, в заголовочном файле библиотеки) должен быть прототип функции void LongToBytes (long LG, char* BYTES, byte Index); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 22 21 июля Опубликовано 21 июля · Жалоба 58 minutes ago, onic777 said: Что не так с вызовом? компилятор вашего файла не видит прототип этой функции нужно перед применением любых функций делать видимыми их прототипы, которые обычно размещают в соотв. h-файлах, которые уже нужно инклудит в ваш код void LongToBytes (long LG, char* BYTES, byte Index); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 228 21 июля Опубликовано 21 июля · Жалоба 2 часа назад, onic777 сказал: Имеется бибмлиотечная функция void LongToBytes (long LG, char* BYTES, byte Index) { byte i; for (i=0;i<4;i++) { BYTES[Index+i] = (*((unsigned char *)&(LG)+i)); } } В тесте программы используется массив байтов, объявленый как byte PID_CODE[4]; раннее uint8_t объявлен как byte Библиотечная функция вызывается как LongToBytes (ADDRESS,PID_CODE,0); При компиляции выдается warning: #223-D: function "LongToBytes" declared implicitly Что не так с вызовом? Функцию объявленную как: void LongToBytes (long LG, char * BYTES, byte Index) Вызываете как: void LongToBytes (long LG, byte * BYTES, byte Index) И видимо определение типа byte у вас не эквивалентно типу char. Перепишите вызов так: LongToBytes (ADDRESS, (char *)&PID_CODE[0], 0); и тогда (возможно!) всё будет ок. ЗЫ: Зачем так громоздко копировать? У вас же Cortex-M3. Он умеет невыровненный доступ. А значит можно например так: Цитата #pragma pack(push, 1) union { unsigned long d; byte b[4]; } PID_CODE; #pragma pack(pop) ... PID_CODE.d = LG; Ну или как-то более компактно описать пакованный тип (если Keil позволяет). Будет всего одна команда записи в память, вместо функции и цикла. 1 час назад, Arlleex сказал: Где-то выше точки вызова в глобальном пространстве (например, в заголовочном файле библиотеки) должен быть прототип функции void LongToBytes (long LG, char* BYTES, byte Index); Автор вызывает как: void LongToBytes (long LG, byte * BYTES, byte Index) Что вроде как эквивалентно: void LongToBytes (long LG, uint8_t * BYTES, byte Index) И не эквивалентно: void LongToBytes (long LG, char * BYTES, byte Index) А прототипов, соответствующих первому и второму вариантам, в коде видимо нет. Отсюда и предупреждение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 21 июля Опубликовано 21 июля · Жалоба 37 минут назад, jcxz сказал: Автор вызывает как: void LongToBytes (long LG, byte * BYTES, byte Index) Что вроде как эквивалентно: void LongToBytes (long LG, uint8_t * BYTES, byte Index) И не эквивалентно: void LongToBytes (long LG, char * BYTES, byte Index) А прототипов, соответствующих первому и второму вариантам, в коде видимо нет. Отсюда и предупреждение. А причем тут разные типы? Автор спрашивал за конкретный варнинг, а не за (возможные) варнинги неявных преобразований указателей. Именно на отсутствующий прототип я и указал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 228 21 июля Опубликовано 21 июля · Жалоба 1 минуту назад, Arlleex сказал: А причем тут разные типы? Автор спрашивал за конкретный варнинг, а не за (возможные) варнинги неявных преобразований указателей. При том, что неявное преобразование типа byte * -> char * компилятор автора видимо не умеет. Поэтому не может использовать имеющееся: void LongToBytes (long LG, char * BYTES, byte Index) без явного приведения типа. Имхо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 21 июля Опубликовано 21 июля · Жалоба 1 час назад, jcxz сказал: При том, что неявное преобразование типа byte * -> char * компилятор автора видимо не умеет. Поэтому не может использовать имеющееся: void LongToBytes (long LG, char * BYTES, byte Index) Что значит не умеет? Он не может не уметь, ибо это преобразование допустимо в любых компиляторах Си, однако компилятор любезно "наводит на мысль" о том, что автору бы еще на знак обратить внимание. Поместите прототип этой функции в нужное место, и варнинг при приведении указателей останется, никуда не денется. Но это как был, так и останется другим типом варнинга - не как у автора. А у автора Цитата function "LongToBytes" declared implicitly что, во-первых, сразу говорит о том, что в точке вызова функции не видно ее объявления, а во-вторых, сразу видно, что функцию автор определил не в том же файле, где ее вызывает. Иначе бы возник конфликт объявлений и это уже не варнинг, а ошибка, и проект не собрался бы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 228 21 июля Опубликовано 21 июля · Жалоба 50 минут назад, Arlleex сказал: Что значит не умеет? Он не может не уметь, ибо это преобразование допустимо в любых компиляторах Си Наверное всё-же - не в любых. IAR 7.80.4, си-файл: typedef unsigned char byte; byte PID_CODE[4]; void LongToBytes(long LG, char* BYTES, byte Index); void mm1(void); void LongToBytes(long LG, char* BYTES, byte Index) { byte i; for (i=0;i<4;i++) { BYTES[Index+i] = (*((unsigned char *)&(LG)+i)); } } void mm1(void) { LongToBytes(0x4445, PID_CODE, 0); LongToBytes(0x4445, (char *)&PID_CODE[0], 0); } результат: Warning[Pe167]: argument of type "byte *" is incompatible with parameter of type "char *" B:\TST\11.c 27 варнинг Pe167 на первую строку mm1(). 50 минут назад, Arlleex сказал: что, во-первых, сразу говорит о том, что в точке вызова функции не видно ее объявления, а во-вторых, сразу видно, что функцию автор определил не в том же файле, где ее вызывает. Иначе бы возник конфликт объявлений и это уже не варнинг, а ошибка, и проект не собрался бы. Возможно вы правы. Не буду гадать - что там у автора, так как половину необходимой для понимания инфы он скрыл. Я просто говорил, что объявление функции нужно не такое, какое вы приводили. А с типом указателя byte *. Ну или добавить ещё приведение типа. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 21 июля Опубликовано 21 июля · Жалоба 1 час назад, jcxz сказал: Наверное всё-же - не в любых. IAR 7.80.4, си-файл: результат: Warning[Pe167]: argument of type "byte *" is incompatible with parameter of type "char *" B:\TST\11.c 27 варнинг Pe167 на первую строку mm1(). Самое главное здесь - это то, что компилятор проглотил это и не выдал ошибку (несмотря на то, что выдался варнинг бонусом). Это не дает IAR-у "быть в стороне" - в нем точно так же преобразование допустимо. Вся соль в том, что этот варнинг просто говорит "программист, будь внимательнее, тут ты беззнаковый преобразуешь в обычный char", но скрытых подводных граблей Си в виде каких-нибудь UB здесь точно нету. И это самое главное. Когда программист увидит этот варнинг, он может "подписать уговор", или задуматься и по-другому все это вообще написать. P.S. Насчет ошибки (которую Вы удалили, p045, вроде). Обявление void mm() не является прототипом функции. И в этом вся загвоздка, это из той же оперы, о которой я говорил 1 час назад, Arlleex сказал: во-вторых, сразу видно, что функцию автор определил не в том же файле, где ее вызывает. Иначе бы возник конфликт объявлений и это уже не варнинг, а ошибка, и проект не собрался бы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 51 21 июля Опубликовано 21 июля · Жалоба Знание стандарта Си сильно помогает. Особенно экономит время при гадании о значении предупреждений или ошибок. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 21 июля Опубликовано 21 июля · Жалоба On 7/21/2024 at 1:44 PM, Arlleex said: Автор спрашивал за конкретный варнинг, а не за (возможные) варнинги неявных преобразований указателей. Не верно. Автор спрашивает про конкретный варнинг. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 21 июля Опубликовано 21 июля · Жалоба @dimka76 прочитайте, что написали и что цитируете)) Вспомнился момент из известной комедии Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 21 июля Опубликовано 21 июля · Жалоба On 7/21/2024 at 6:50 PM, Arlleex said: @dimka76 прочитайте, что написали и что цитируете)) А что не так ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 21 июля Опубликовано 21 июля · Жалоба 1 минуту назад, dimka76 сказал: А что не так ? 😀 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 21 июля Опубликовано 21 июля · Жалоба On 7/21/2024 at 6:56 PM, Arlleex said: 😀 Ой, вы никак намек понять не можете. Примененный вами предлог ЗА в данном контексте уместно употреблять только сидя на корталял и с семками в руках Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться