在下面的虚拟示例中,我收到警告,但我不明白如何在没有明确定义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非常相似,但它并没有解释为什么我不能这样做以及为什么我会收到错误。
答案 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_t
和int32_t
。简而言之,两种类型具有不同的大小。
如果你想将int32_t*
强制转换为int64_t*
,请为其指定一个值并将指针递增后,你可能已经写了如下(从你的例子中得到启示):
int32_t* p = &value;
*((int64_t*)p++) = 42;
根据运营商precedence,订单执行是:
此示例构建完美,但它没有按照您的想法执行。想要的是增加转换指针。所以你还需要一个括号:
*(((int64_t*)p)++) = 42;
这次,您会收到错误,因为((int64_t*)p)
被视为lvalue
,因此无法修改。
在这种特殊情况下,你绝对需要第三个变量来完成这个技巧。
这与您的void
指针完全相同。