Почему нормально использовать строковый литерал для инициализации массива без знака, но не для инициализации указателя без знака? - PullRequest
0 голосов
/ 05 ноября 2018

Я попытался скомпилировать с gcc -Wall -pedantic-errors -std=c89 следующий код:

int main(){
  unsigned char a[] = "foo";
  unsigned char *b= "foo";
  unsigned char *c= ( unsigned char *) "foo";
  return 0;
}

Почему при второй инициализации возникает ошибка pointer targets in initialization differ in signedness, но разрешены два других объявления?

Похоже, что во втором случае неявное преобразование из char * в unsigned char * не выполняется.

1 Ответ

0 голосов
/ 05 ноября 2018

Технически, поскольку стандарт явно разрешает инициализировать массивы (любого) символьного типа строковыми литералами ( 6.7.9p14 ):

Массив символьного типа может быть инициализирован символьной строкой литерал или строковый литерал UTF-8, необязательно заключенный в фигурные скобки. Последовательные байты строкового литерала (включая завершающий ноль) символ, если есть место или если массив имеет неизвестный размер) инициализировать элементы массива.

, в то время как для большинства преобразований указателей стандарт требует явного приведения ( 6.5.4p3 ):

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

Интуитивно, потому что вы можете сделать:

unsigned char a0 = 'f', a1 = 'o', a2 = 'o';

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...