Могу ли я прочитать любую читаемую допустимую область памяти через (без знака) символ * в C ++? - PullRequest
5 голосов
/ 09 июля 2011

Похоже, что в моем поиске foo сегодня не хватает.

Я хотел бы знать, является ли допустимым в соответствии со стандартом C ++ для проверки "любой" ячейки памяти через (без знака (?))символ *.Под любым местоположением я подразумеваю любой действительный адрес объекта или массива (или внутри массива) внутри программы.

В качестве примера:

void passAnyObjectOrArrayOrSomethingElseValid(void* pObj) {
   unsigned char* pMemory = static_cast<unsigned char*>(pObj)
   MyTypeIdentifyier x = tryToFigureOutWhatThisIs(pMemory);
}

Отказ от ответственности : Этот вопрос носит чисто академический характер.Я не собираюсь помещать это в производственный код!Под Legal Я имею в виду, если это действительно Legal в соответствии со стандартом, то есть если он будет работать на 100% всех реализаций.(Не только на x86 или некоторых других аппаратных средствах.)

Подвопрос: static_cast является ли правильным инструментом для перехода от адреса void * к указателю char *?

Ответы [ 3 ]

6 голосов
/ 09 июля 2011

C ++ предполагает строгое псевдонимы, что означает, что два указателя принципиально другого типа не имеют псевдонимов одинакового значения.

Однако, как правильно указывает bdonlan, стандарт делает исключение для char и unsigned char указатели.

Таким образом, в общем случае это неопределенное поведение для любого типа указателя для чтения любого преднамеренного адреса (который может быть любого типа), но для частного случая unsigned charкак и в вопросе, это разрешено (ISO 14882: 2003 3.10 (15)).

static_cast выполняет проверку типов во время компиляции, поэтому вряд ли она всегда будет работать.В таком случае вам понадобится reinterpret_cast.

2 голосов
/ 09 июля 2011

В соответствии с ИСО / МЭК 9899: 1999 (E).

  • тип, совместимый с эффективным типом объекта,
  • [...]
  • тип символа

Таким образом, законно (в C) разыменовать и проверять (действительный) указатель через unsigned char.Тем не менее, содержимое, которое вы найдете там, не указано;tryToFigureOutWhatThisIs не имеет четко определенного способа выяснить, на что он смотрит.У меня нет здесь копии спецификации C ++, но я подозреваю, что она использует то же определение для обеспечения совместимости.

0 голосов
/ 09 июля 2011

Вы можете использовать только char*, а не unsigned char*. Использование unsigned char* нарушит строгие правила псевдонимов и вызовет неопределенное поведение, но есть исключение для char*. Однако попытка что-либо сделать с памятью, которую вы читаете, очень сомнительна и, скорее всего, сделает что-то неопределенное. Вот почему это редко делается в идиоматическом коде C ++.

...