Отправка строки C в неподписанный char указатель
Я компилирую код низкого уровня, используя много пучков байтов. В некоторых случаях мне удобно определить, используя двойные кавычки, вложенные в старые строки C.
Но при компиляции с помощью gcc или g++ (не знаю поведения с другими компиляторами), он продолжает беспокоить меня знаком указательной строки.
В основном, когда я пишу это
const unsigned char & refok = *"ABCDEFGHI";
РЕДАКТИРОВАТЬ: хорошо, код выше не работает, так как теоретически просто сохранит ссылку на копию первого char строки. Фактически это разрешает доступ ко всей строке с некоторыми компиляторами из-за оптимизации, но может прерываться в любое время.
или
const unsigned char oktoo[10] =
{'A','B','C','D','E','F','G','H','I',0};
компилятор ничего не говорит.
Но он определенно отвергает это:
const unsigned char * bad = "ABCDEFGHI";
с сообщением
error: invalid conversion from
‘const char*’ to ‘const unsigned char*’
[-fpermissive]
Это даже не предупреждение, это ошибка.
Мне интересно, почему этот вопрос должен быть более проблематичным, чем при использовании ссылки или преобразовании отдельных символов из подписанных символов в неподписанные символы? Или я что-то упускаю?
Ответы
Ответ 1
Я думаю, что вам не хватает много чего!
Первая строка, вероятно, делает что-то совершенно отличное от того, что вы думаете. (Он включает преобразование и продление срока службы временного.)
Вторая строка инициализирует каждый unsigned char из соответствующего char в инициализаторе скобок.
В третьей строке компилятор прав: строковый литерал имеет тип const char *
, и вы не можете преобразовать T*
в U*
вообще.
Обратите внимание, что стандарт требует явно, чтобы char
, unsigned char
и signed char
были разными типами. Примером здесь является то, что char
должен быть базовым байтовым типом платформы, а два других - явно неподписанными и подписанными интегральными типами. Беззнаковые/подписанные типы предназначены для алгебраических операций, а голый тип - для взаимодействия с системой (например, аргументы командной строки и ввода/вывода файлов).
Ответ 2
Разрешены неявные преобразования между числовыми типами; это то, что делают первые два. Неявные преобразования между разными типами указателей не допускаются (кроме преобразования указателя производного класса в указатель базового класса).
Обратите внимание, что первое не дает ссылки на первый символ массива. Он создает временную копию этого символа, преобразуется в тип unsigned char
и связывает ссылку с этим, продлевая время жизни временного до ссылки.
Второй преобразует каждый char
в список инициализации в элемент массива unsigned char
.
Третья попытка конвертировать const char *
в const unsigned char *
; поскольку char
и unsigned char
являются разными типами, неявное преобразование указателя не допускается.