Перейти к содержанию
    

Простой вопрос по синтаксису Keil ARM

Добрый день, Уважаемые коллеги!

Я работаю в среде 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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Где-то выше точки вызова в глобальном пространстве (например, в заголовочном файле библиотеки) должен быть прототип функции

void LongToBytes (long LG, char* BYTES, byte Index);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

58 minutes ago, onic777 said:

Что не так с вызовом?

компилятор вашего файла не видит прототип этой функции

нужно перед применением любых функций делать видимыми их прототипы, которые обычно размещают в соотв. h-файлах, которые уже нужно инклудит в ваш код

void LongToBytes (long LG, char* BYTES, byte Index);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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)

А прототипов, соответствующих первому и второму вариантам, в коде видимо нет. Отсюда и предупреждение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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)

А прототипов, соответствующих первому и второму вариантам, в коде видимо нет. Отсюда и предупреждение.

А причем тут разные типы? Автор спрашивал за конкретный варнинг, а не за (возможные) варнинги неявных преобразований указателей.

Именно на отсутствующий прототип я и указал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, Arlleex сказал:

А причем тут разные типы? Автор спрашивал за конкретный варнинг, а не за (возможные) варнинги неявных преобразований указателей.

При том, что неявное преобразование типа byte * -> char * компилятор автора видимо не умеет. Поэтому не может использовать имеющееся: void LongToBytes (long LG, char * BYTES, byte Index)

без явного приведения типа.

Имхо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, jcxz сказал:

При том, что неявное преобразование типа byte * -> char * компилятор автора видимо не умеет. Поэтому не может использовать имеющееся: void LongToBytes (long LG, char * BYTES, byte Index)

Что значит не умеет? Он не может не уметь, ибо это преобразование допустимо в любых компиляторах Си, однако компилятор любезно "наводит на мысль" о том, что автору бы еще на знак обратить внимание.

Поместите прототип этой функции в нужное место, и варнинг при приведении указателей останется, никуда не денется. Но это как был, так и останется другим типом варнинга - не как у автора. А у автора

Цитата

function  "LongToBytes" declared implicitly

что, во-первых, сразу говорит о том, что в точке вызова функции не видно ее объявления, а во-вторых, сразу видно, что функцию автор определил не в том же файле, где ее вызывает. Иначе бы возник конфликт объявлений и это уже не варнинг, а ошибка, и проект не собрался бы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 *. Ну или добавить ещё приведение типа.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 сказал:

во-вторых, сразу видно, что функцию автор определил не в том же файле, где ее вызывает. Иначе бы возник конфликт объявлений и это уже не варнинг, а ошибка, и проект не собрался бы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Знание стандарта Си сильно помогает. Особенно экономит время при гадании о значении предупреждений или ошибок.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/21/2024 at 1:44 PM, Arlleex said:

Автор спрашивал за конкретный варнинг, а не за (возможные) варнинги неявных преобразований указателей.

Не верно.
Автор спрашивает про конкретный варнинг.
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/21/2024 at 6:50 PM, Arlleex said:

@dimka76 прочитайте, что написали и что цитируете))

А что не так ? :blush:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/21/2024 at 6:56 PM, Arlleex said:

image.png.8160bbc817b98d5c7bbff97d845cdf6f.png

😀

Ой, вы никак намек понять не можете. 
Примененный вами предлог ЗА в данном контексте уместно употреблять только сидя на корталял и с семками в руках :sarcastic:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...