Что происходит, когда у кастового указателя есть оператор инкремента?

Например:

int x[100];
void *p;

x[0] = 0x12345678;
x[1] = 0xfacecafe;
x[3] = 0xdeadbeef;

p = x;
((int *) p) ++ ;

printf("The value = 0x%08x", *(int*)p);

Компиляция выше генерирует требуемую ошибку lvalue в строке с оператором ++.

Ответы

Ответ 1

Приведение создает временный указатель типа int *. Вы не можете увеличивать время, поскольку оно не обозначает место для хранения результата.

В C и С++ standardese (int *)p является rvalue, что примерно означает выражение, которое может появляться только в правой части присваивания.

p, с другой стороны, это lvalue, что означает, что он может корректно отображаться в левой части задания. Только lvalues ​​могут быть увеличены.

Ответ 2

Выражение ((int *) p) рассматривает указатель, хранящийся внутри переменной p, является указателем на int. Если вы хотите обработать эту переменную как указатель на переменную int (а затем увеличьте ее), используйте ссылку:

((int *&) p) ++ ;

Ответ 3

Вы можете получить ожидаемый результат с помощью

p = (int*)p + 1;

Использование оператора инкремента по разыменованному указателю на p, который является lvalue, также работает:

(*(int**)&p)++;

Однако последнее не переносимо, поскольку (void*)p может не иметь того же представления, что и (int*)p.

Ответ 4

Благодаря larsmans для указания в правильном направлении.

Я позволил себе углубиться в это. Поэтому для дальнейшего использования в соответствии с разделами 6.5.2.4 и 6.5.4 стандарта C99 (http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf):

6.5.2.4 Операторы приращения и уменьшения постфикса

Ограничения

Операнд приращения postfix или декремент должен иметь квалифицированных или неквалифицированных реальных или тип указателя и должен быть модифицируемым именующее
..
..
6.5.4 Операторы роли
..
..
[Сноска] 89) Литой не дает lvalue. Таким образом, литой к квалифицированному типу эффект как приведение к неквалифицированному версии типа.

Примечание. Это относится только к C. С++ может обрабатывать отливки по-разному.

Ответ 5

выражение Rvalue ((int *) p) создает и временное значение типа int*, при котором оператор ++ не может быть применен.

++ требуется lvalue как его операнд.

Поскольку @FredOverflow упоминает lvalues и rvalues, очень мало связано с назначением.

Массивы - это lvalues, но они не могут быть назначены, потому что они не изменяемы. std::string("Prasoon") - выражение rvalue, которое все же может иметь место в левой части оператора присваивания, потому что нам разрешено вызывать функции-члены (operator = в этом случае) во временных рядах.