Предупреждение 359 при передаче строки в символ * - PullRequest
0 голосов
/ 08 ноября 2018

Я пытаюсь передать строку в функцию:

void PassString(unsigned char * value)
{
    // ...
}

int main(void)
{
    while(1)
    {
        PassString("TEST");
    }
}

Я получаю предупреждение: (359) недопустимое преобразование между типами указателей.

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Краткий ответ:

Строковые литералы, такие как "TEST", имеют тип char[] в C.

Поэтому измените функцию, чтобы принять char*. Или приведите аргумент к unsigned char*, хотя это менее чистое решение.


Некоторая история позади char:

Система типов C немного не функционирует, когда дело касается типов символов. На заре времени, когда динозавры шли по земле, не было указано, должно ли char быть signed или unsigned по умолчанию.

signed имеет смысл, потому что это делает char совместимым с целыми типами большего размера. unsigned также имеет смысл, поскольку не существует таблиц символов с отрицательными индексами.

После стандартизации языка уже существовали различные компиляторы, которые давали char разную подпись. Поэтому было решено, что подпись char должна определяться реализацией. То есть: каждый компилятор решает.

По той же причине типы char, signed char и unsigned char были заявлены как 3 различных типа. Это означает, что вы не можете неявно конвертировать указатели в эти типы. Вместо этого вам нужно использовать явное преобразование путем приведения.

Только странные персонажи ведут себя так странно. Например, если вы берете int и signed int, они всегда совместимы, а int всегда подписано.

Это известный недостаток языка Си. Поэтому типы из библиотеки stdint.h предпочтительнее «необработанных» типов символов.


Лучшая практика использования типов символов:

  • Используйте тип char, если вы имеете дело с (до 8 бит) текстовыми строками, и только затем.
  • Используйте тип unsigned char или uint8_t, если вы работаете с необработанными двоичными данными или выполняете штампование и т. Д.
  • Используйте signed char или int8_t, если вы выполняете 8-разрядную целочисленную арифметику со знаком.
  • Используйте unsigned char или uint8_t, если вы выполняете 8-разрядную целочисленную арифметику без знака.
  • Нет никакой опасности превращения между различными типами символов, если не имеет значения подпись.
  • Но ... будьте осторожны при выполнении любой формы арифметики с этими типами, так как она сопряжена со многими подводными камнями. См. Правила продвижения неявных типов .
0 голосов
/ 08 ноября 2018

Передаваемый строковый литерал имеет тип char [], но аргумент задается как unsigned char *.

Поэтому измените тип аргумента на char[].

...