Преобразование между uint8_t * и char *. Что происходит?

#objective-c #c #string #casting

#objective-c #c #строка #Кастинг

Вопрос:

Что происходит при приведении между этими двумя в отношении символа завершения? В C99 Objective-C.

Комментарии:

1. Единственное, что делает приведение, это избавляется от предупреждений компилятора, если только вы не преобразуете значение с плавающей запятой в целое число или наоборот. Выходной код точно такой же.

2. Это неправда. Язык C не определяет никакого неявного преобразования между различными типами указателей (кроме void * , конечно). Приведение — это единственный способ преобразования. Компилятор, который допускает преобразование без приведения и генерирует только предупреждение, ошибочно «щедр» по отношению к вам; это неправильно.

Ответ №1:

Я предполагаю, что в этом ответе значение char в вашей системе равно 8 битам.

Если в вашей архитектуре используется тип unsigned char as char , то абсолютно ничего не произойдет.

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


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

Комментарии:

1. Спасибо, но я думал, что некоторые типы были преобразованы специально. Например, float в int . Это должно быть преобразовано. Но что касается указателей, с данными при любом приведении никогда ничего не происходит?

2. преобразование значения float в значение int преобразует значение при копировании. Преобразование указателя на блок целых чисел в значения с плавающей точкой просто оставит вас со странными значениями в числах с плавающей точкой — ничего не изменится

3. Конечно, да. Не знал, были ли исключения. Я где-то нашел веб-сайт, на котором неправильно говорилось о uint8_t и char, что меня смутило, поэтому мне пришлось прийти сюда.

4. @Matthew Mitchell: На каком веб-сайте?

5.Если char не 8-разрядный, то он uint8_t не может существовать, и в этом нет вопроса.

Ответ №2:

Если char и uint8_t являются совместимыми типами (они должны быть на большинстве современных настольных компьютеров), указатели на объекты этого типа имеют одинаковые требования к представлению и выравниванию, поэтому не должно возникнуть проблем с преобразованием (неявно или явно с приведением) одного в другой.

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

Примечание: я не уверен на 100%, что uint8_t и char совместимы в реализации со знаковыми символами.

Если типы несовместимы, вы вызываете неопределенное поведение, и может произойти что угодно: очень вероятно, что все «работает» так, как вы ожидаете — но нет гарантии, что это всегда будет работать одинаково

Комментарии:

1. Независимо от совместимости, вы не вызывали UB. Любой тип может быть доступен как наложенный массив unsigned char [sizeof(type)] .

2. Хммм … конечно! Я просто представлял, что uint8_t это несовместимо с char , но я не могу представить, что uint8_t существует и быть несовместимым с char .

3. Я не думаю, что они считаются «совместимыми», если char не случается, что они беззнаковые; просто это unsigned char особенное и может получить доступ к чему угодно. На самом деле, технически я полагаю, что uint8_t это может быть «расширенный целочисленный тип» с теми же свойствами, что и unsigned char , за исключением свойств сглаживания, и в этом случае код может вызывать UB….