【问题标题】:Casting pointer to void将指针转换为 void
【发布时间】:2016-01-12 16:45:57
【问题描述】:

下面两个铸件有什么区别吗?

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

Just saw that in this answer.(显然我误解了什么)

【问题讨论】:

    标签: c pointers void


    【解决方案1】:

    当你这样做时

    (void) p;
    

    您告诉编译器简单地忽略表达式p 的结果。它实际上与空语句相同:

    ;
    

    当你这样做时

    (void *) p;
    

    您告诉编译器将变量 p 视为通用指针,这就是该语句的完整表达式,一个实际上没有任何作用的表达式,您会收到错误消息。

    【讨论】:

    • 您能否介绍一下此功能的实际使用情况?
    • @DavidHaim:我已经在某些局部变量仅在 IFDEF 中使用的情况下看到它,以便在使用采用 @ 的设置编译时不会引发警告987654327@分公司。
    • 大声笑,所以在 ELSE 分支中声明局部变量,如果它是唯一接触它的地方。或者我猜它是从你在范围开始时一起声明所有变量的时期开始的..
    • “它实际上与空语句相同”-> C 中几乎任何表达式都有副作用。这个答案目前暗示编译器可能会将(void)sideEffectingFunction(a = b, c++); 减少到;,显然情况并非如此。
    • @DavidHaim 将变量转换为void 是一种消除潜在编译器警告未使用函数参数的方法。
    【解决方案2】:

    是的,很明显。

     (void)p;
    

    意味着对象被强制转换为void 类型,(这不是一个完整的类型)并且作为完整的表达式,不应使用表达式的结果,因此编译器不会检查它的用法。

    引用 C11 标准,第 6.3.2.2 章,void

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

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

    哦,

    (void *)p;
    

    表示该对象是指向void 类型的指针,这是一个完整的类型,应该在您的程序中使用。在这种情况下,编译器会正确地报告表达式中没有使用对象。

    【讨论】:

    • p指向的地址之前的转换值,有什么变化吗?
    • @ameyCU 不。只有有s副作用才会生效,这里不是这样。
    • 然后再次将p 转换为int * 会安全吗?
    • @ameyCU 是的,它会的,但你不需要那个。
    • 为什么我不需要那个?因为我首先要投给void
    猜你喜欢
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 2021-07-22
    • 2012-11-21
    • 1970-01-01
    • 2021-09-20
    • 2023-03-26
    相关资源
    最近更新 更多