Почему указатель на символ получает 32-битное значение (ffffff88) - PullRequest
0 голосов
/ 22 июня 2019
int in=0xeef01f88;
int * ipoi=∈
char*cpoi=(char*)ipoi;
cout<<std::hex<<(int)*ipoi<<" "<<(int)*(cpoi)<<" "<<(int)*(cpoi+1)<<" "<<(int)*(cpoi+2)<<endl;

Когда я компилирую это на Cxxdroid (компилятор Android), он работает отлично, как и должно быть, поэтому cout из указателей на символы дает значения отдельных байтов, такие как:

eef01f88 88 1f f0.

Другой способ, когда я компилирую тот же код в Windows, используя GNU GCC COMPILER, я получил такой вывод:

eef01f88 ffffff88 1f fffffff0.   

Как это возможно? Почему первое и третье значения указателя на символ имеют ffffff сами по себе? Вокруг *(cpoi+1) даже нет значений ff. (F0) Поможет ли смена компилятора решить проблему?

Я использую блоки кода. В нем есть много вариантов компиляции, но я уже попробовал все доступные стандарты (до 2011 года стандарт языка ISO C). Чего мне не хватает?

1 Ответ

1 голос
/ 23 июня 2019

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

  • На ARM char обычно является беззнаковым типом , потому что более эффективен , поэтому приведение char к int приводит к нулевому расширению
  • В большинстве случаев char является типом со знаком по умолчанию, поэтому эти байты будут подписаны и расширены до int. Поскольку 0x88 и 0xf0 отрицательны, они будут иметь один бит в старшей части

Решение состоит в том, чтобы избежать char и использовать вместо него signed char или unsigned char, или обойти, добавив опцию для изменения сигнатуры char (-funsigned-char в gcc). Или, что еще лучше, используйте типы фиксированной ширины, такие как uint8_t и int8_t

См

...