将指针转换为void

15

以下两种铸件有何不同之处?

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编译时。

我在这个答案中看到了这个命令。(显然我误解了某些事情)

2个回答

15

当你执行时

(void) p;

你告诉编译器仅仅忽略表达式 p 的结果。这和一个空语句是一样的效果:

;

当你做

(void *) p;

你告诉编译器将变量p视为通用指针,这就是语句的完整表达式,但实际上它并没有做任何事情,因此你会收到错误信息。


你能给一些这个功能的实际应用例子吗? - David Haim
1
@DavidHaim:我曾经在某些情况下看到过这种情况,其中某些本地变量仅在 IFDEF 内部使用,以使其在使用 ELSE 分支的设置进行编译时不会引发警告。 - Mason Wheeler
“这实际上与空语句相同”,C语言中几乎任何表达式都可能具有副作用。当前的答案暗示编译器可能会将(void)sideEffectingFunction(a = b, c++);简化为;,但显然并非如此。 - Alex Celeste
@Leushenko 当然这不是普遍情况,但对于这个情况来说基本上是等价的。 - Some programmer dude
2
@DavidHaim 把一个变量转换为 void 是一种消除潜在编译器警告的方法,以防止未使用的函数参数。 - Some programmer dude
显示剩余2条评论

14

是的,显然。

 (void)p;

表示对象被强制转换为 void 类型(这不是完整的类型),作为完整表达式,不能使用表达式结果,因此编译器不会检查它的使用情况。

引用 C11 标准,第 6.3.2.2 章节,关于 void

  

一个无类型表达式(具有 void 类型的表达式)的(不存在的)值不得以任何方式使用,[...] 如果将任何其他类型的表达式评估为 void 表达式,则其值或指示符将被丢弃。

因此,不会生成警告或错误。

另一方面,

(void *)p;

指针的对象是 void 类型,它是一个完整的类型,应该在程序中使用。在这种情况下,如果对象未在表达式之外使用,则编译器会正确报告。


通过前面的强制类型转换,指针 p 所指向的地址的值是否发生了任何变化? - ameyCU
@ameyCU 是的,它会,但你不需要那个。 - Sourav Ghosh
为什么我不需要那个?因为我一开始就转换为空void - ameyCU
@ameyCU 但是你把它存储在哪里了? :) - Sourav Ghosh
那么为什么它会对 p 本身产生任何影响呢? :) - Sourav Ghosh
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接