增加的类型参数错误

时间:2017-03-17 10:44:34

标签: c pointers

在下面的虚拟示例中,我收到警告,但我不明白如何在没有明确定义int *_str = (int*)str的指针的情况下摆脱它:

#include <stdlib.h>
#include <stdint.h>

void foo(void *str, int c, size_t n) {
    for (size_t i = 0; i < n; i++)
        *((int*)str++) = c;
}

以下是gcc中的内容:

gcc -c -std=c99 -Wpointer-arith test.c
test.c: In function ‘mymemset’:
test.c:7:20: warning: wrong type argument to increment [-Wpointer-arith]
         *((int*)str++) = c;
                    ^

我的代码出了什么问题?

注意

我知道这个问题与one非常相似,但它并没有解释为什么我不能这样做以及为什么我会收到错误。

2 个答案:

答案 0 :(得分:1)

str是指向void的指针。由于void很好,无效且没有大小,所以可怜的编译器怎么可能理解str++的含义?

str++应该使str指向下一个对象,但由于类型void不能是任何对象的类型str++没有意义。

虽然你被转换为int *,但++更像是“绑定”(这里“优先”这个词混淆了)而不是演员。

答案 1 :(得分:0)

你觉得自己陷入了X-Y问题,因为你误解了*((int*)str++) = c应该做什么。所以你的问题不是void算术,而是lvalue后增量。

让我们将void问题分开一段时间,并考虑在32位架构字节上可寻址的大小为8和4的int64_tint32_t。简而言之,两种类型具有不同的大小。

如果你想将int32_t*强制转换为int64_t*,请为其指定一个值并将指针递增后,你可能已经写了如下(从你的例子中得到启示):

int32_t* p = &value;
*((int64_t*)p++) = 42; 

根据运营商precedence,订单执行是:

  1. 采取p
  2. 将其保存为后增量为int32_t *
  3. 将其投射到int64_t *
  4. 取消引用它并将42指定为int64_t
  5. 后增量p
  6. 此示例构建完美,但它没有按照您的想法执行。想要的是增加转换指针。所以你还需要一个括号:

    *(((int64_t*)p)++) = 42; 
    

    这次,您会收到错误,因为((int64_t*)p)被视为lvalue,因此无法修改。

    在这种特殊情况下,你绝对需要第三个变量来完成这个技巧。

    这与您的void指针完全相同。