Указатель кастинга на пустоту

Есть ли разница в ниже двух отливок?

int a=10;
int *p=&a;

(void)p;          //does not give any warning or error 

или

(void *)p;        //error: statement with no effect [-Werror=unused-value]

при соблюдении gcc -Wall -Werror --std=c99 -pedantic

Просто увидел это в этом ответе. (ясно, я что-то не понял)

Ответ 1

Да, очевидно.

 (void)p;

означает, что объект получает литой тип void (который не является полным типом) и что это полное выражение, результат выражения не должен использоваться, поэтому компилятор не проверяет его использование.

Цитата C11 стандарт, глава 6.3.2.2, void

(несуществующее) значение выражения void (выражение, которое имеет тип void) не должно [......] Если выражение любого другого типа оценивается как voidвыражение, его значение или указатель отбрасываются.

Таким образом, никаких предупреждений и ошибок не генерируется.

OTOH,

(void *)p;

означает, что объект является указателем на тип void, который является полным типом и должен использоваться в вашей программе. В этом случае компилятор правильно сообщает об отсутствии использования объекта вне выражения.

Ответ 2

Когда вы делаете

(void) p;

Вы говорите компилятору просто игнорировать результат выражения p. Это фактически то же самое, что и пустой оператор:

;

Когда вы делаете

(void *) p;

Вы говорите компилятору рассматривать переменную p как общий указатель и что полное выражение для оператора - выражение, которое на самом деле ничего не делает, и вы получаете сообщение об ошибке.