#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….