Ответ 1
Да, очевидно.
(void)p;
означает, что объект получает литой тип void
(который не является полным типом) и что это полное выражение, результат выражения не должен использоваться, поэтому компилятор не проверяет его использование.
Цитата C11
стандарт, глава 6.3.2.2, void
(несуществующее) значение выражения
void
(выражение, которое имеет тип void) не должно [......] Если выражение любого другого типа оценивается какvoid
выражение, его значение или указатель отбрасываются.
Таким образом, никаких предупреждений и ошибок не генерируется.
OTOH,
(void *)p;
означает, что объект является указателем на тип void
, который является полным типом и должен использоваться в вашей программе. В этом случае компилятор правильно сообщает об отсутствии использования объекта вне выражения.