Результат приведения не является lvalue. В разделе 6.5.4 Cast operators
ISO C11 есть сноска, в которой говорится:
Приведение не дает lvalue. Таким образом, приведение к квалифицированному типу имеет тот же эффект, что и приведение к неквалифицированной версии этого типа.
Аналогично, в 6.5.3.1 Prefix increment and decrement operators
говорится (мой акцент):
Операнд префиксного оператора увеличения или уменьшения должен иметь атом c, квалифицированный или неквалифицированный вещественный или указательный тип и должен быть изменяемым lvalue.
Следовательно, то, что вы пытаетесь сделать, недопустимо.
Причина, по которой (int *)ptr2 + 1
работает, заключается в том, что ptr2
является lvalue, поэтому оно может быть бросать. Добавление 1
делается к значению приведения, и это также допустимо.
Ситуация, которую вы пытаетесь, ничем не отличается от ++(ptr+1)
, который является другим способом. попытки увеличить ненулевое значение. Это потому, что и ваше приведение, и выражение ptr+1
являются эфемерными объектами, которые должны существовать достаточно долго, чтобы их можно было использовать для немедленной операции (дополнение или приведение, не до -нкремент).
Ваша проблема исчезнет, если вы слегка переделаете способ выполнения задач (поскольку void*
свободно приводит к большинству других указателей):
printf("%p\n", ptr2 = ((int*)ptr2) + 1);