Отправка строки 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 являются разными типами, неявное преобразование указателя не допускается.