Приведение типов между char* и UBYTE* (unsigned char*)

Фон: я получаю массив как char* как часть сеанса сокета. Теперь мы должны сопоставить токены (заголовки HTTP) из него. Код здесь в том, что мы создали UBYTE * и получили значение из массива символов после приведения типов с помощью UBYTE. Позже тот же указатель UBYTE мы передаем другой функции, которая принимает char* после приведения его типа к char*.

Проблема здесь в том, что это работает в сборке релиза, а не в сборке отладки (с -g и другой оптимизацией). Не только это добавление нескольких отпечатков в режиме отладки скрывает проблему.

Итак, мой вопрос здесь: в чем разница между указателем UByte (который по сути является беззнаковым символом) и указателем char. Замена UByte на char решает мою проблему во всех режимах, но у меня нет объяснения этому? Есть идеи ?


person Aryan    schedule 14.07.2010    source источник


Ответы (2)


Нет ничего плохого в приведении между char * и unsigned char *. Если вы получаете неожиданное поведение, которое варьируется в зависимости от уровней оптимизации, в вашем коде определенно есть ошибка, но она, вероятно, не имеет ничего общего с отбрасыванием подписи в приведении.

Кроме того, UBYTE — довольно нелепое определение типа, поскольку существует стандартный тип C, uint8_t, который идентичен и определен в stdint.h.

person R.. GitHub STOP HELPING ICE    schedule 14.07.2010
comment
@R., небольшое исправление, существование unit8_t обеспечивается POSIX, а не C. - person Jens Gustedt; 14.07.2010
comment
C гарантирует, что он существует, если существует 8-битный целочисленный тип. Если 8-битного типа не существует, определить собственный UBYTE также невозможно. Поскольку этот вопрос касается обработки заголовков HTTP, целью почти наверняка являются платформы, оборудованные для работы с сетевыми единицами данных (байтами). CHAR_BIT!=8 действительно патология, о которой не стоит упоминать. Это никогда не произойдет, за исключением DSP и устаревших машин, которые никогда не станут мишенями для портативных программ. - person R.. GitHub STOP HELPING ICE; 14.07.2010
comment
@R, то, что они назвали его UBYTE, не означает, что он имеет ширину 8. Он показывает только то, что они ожидают. - person Jens Gustedt; 14.07.2010
comment
Если он не имеет ширины 8, то название UBYTE в 1000 раз больше повреждает мозг, чем я уже думал... - person R.. GitHub STOP HELPING ICE; 14.07.2010

Возможно, вы могли бы объяснить, почему вы вообще должны были использовать unsigned char? И что означает не работает?

void*, char* и unsigned char* имеют разную семантику, и вы должны использовать их в соответствии с этим:

  • void* указывает на неспецифические данные, с которыми вы ничего не можете сделать, если не приведете их к некоторому реальному типу
  • char*, к сожалению, имеет два разных значения: либо как текстовая строка, либо как неспецифические данные, но которые могут быть адресованы (исправлены) на низком (байтовом) уровне.
  • signed char и unsigned char — целые числа небольшой ширины, над которыми вы хотите выполнять арифметические операции.
person Jens Gustedt    schedule 14.07.2010
comment
почему я предпочитаю использовать char *, так это использование одного и того же типа данных. Функция 1 Вызывает функцию 2 (передавая параметр char*). Функция 2 копирует его в локальный Ubyte*. Функция 2 вызывает функцию 3 (которая принимает char*). Таким образом, по моему мнению, function2 действует как проход от Function1 до Function3 и без необходимости изменяет его на UBYTE, добавляя накладные расходы на приведение типов или ссылки/удаления ссылок на указатели. PS: я не вижу никакой логической проблемы с моим кодом, поскольку текущий код работает как в выпуске (O2), так и в отладке (O3,g) + дополнительные отпечатки в проблемной функции. - person Aryan; 14.07.2010
comment
Спасибо Женя за ответы и понимание. Просто чтобы прояснить, я не удовлетворен или около того. У меня есть с собой старый написанный код, где люди со временем меняли его на свое усмотрение. Говоря о производственном коде, я имел в виду, что с функциями Parse нет логических проблем, поскольку они выполняются так долго. Я просто пытаюсь понять рациональную разницу между Char* и UBYTE*. Возможно, я ошибаюсь, придерживаясь только этого, и мне следует изучить некоторые другие аспекты кода. :-( - person Aryan; 14.07.2010
comment
@Ayan, я думаю, что в такой настройке сложно что-то узнать. Но если вы должны очистить этот код, хорошей идеей будет начать с более разумной схемы типов. Если вы заметите, что многие неприятные ошибки исчезнут, просто приведя код в порядок таким образом. Удачи в любом случае. - person Jens Gustedt; 14.07.2010