在Visual Studio C ++版本9(以及可能还有其他版本)中,代码如下:
int a = sizeof(void);
void const *b = static_cast<void const *>("hello world");
b += 6;
error C2070: 'void': illegal sizeof operand
error C2036: 'const void *' : unknown size
此代码适用于GCC,它处理sizeof(void)
as 1
。
是否存在某种解决此限制的方法,因为为了指针运算而明确地向char *
进行强制转换会增加混淆(void *
被很好地识别并用作指向原始内存的无类型指针。)< / p>
sizeof(void)
来
表明我很清楚这一事实
它不是1
问题的原因。void
的“正常”方式,但这是C,这些都会发生。这个问题似乎引起了很大的困惑。问题不在于为什么 sizeof(void) == 1
不是标准的,而是在不是标准时该做什么。
在要进行单字节指针运算的情况下,事实证明,转换为char *
是正确的答案,不是因为*(void *)
没有大小,而是因为标准实际保证*(char *)
总是1
。因此,char *
的使用始终是正确的,并且与void *
一致,具有GCC扩展名,用于原始指针算法。
为了进一步强调这一点,void *
是指向无类型内存指针的正确选择,而char *
是强制转换为原始指针算法的正确类型。 / p>
答案 0 :(得分:18)
增加一个指针在技术上应该通过它所指向的任何大小来增加它。无效点无效,因此大小未知。
对于某些编译器来说,它是一个让你增加void指针的好处。
投射很烦人,因为你必须把它投射到另一个指针,然后再回来,或做一些像(*(char *)&voidptr) += 6
就个人而言,我只是为了算术
而将其声明为char *
答案 1 :(得分:10)
在C语言中,sizeof
无法应用于不完整类型。 void
是一个不完整的类型,这就是为什么你不能将它用作sizeof
的操作数。
C中也不支持void *
指针的指针运算。为了与指针运算一起使用,指针必须指向对象类型,void
不是。
GCC允许两者作为一种奇怪的语言扩展。
答案 2 :(得分:6)
void *
意味着暗示“指向未知的指针”
因此,未定义向void指针添加6,因为您要求编译器将指针前进“6个未知对象的大小”。
你不应该这样做。
答案 3 :(得分:3)
这里有两个不同的问题。第一个是void
,第二个是void*
。它们是不同的类型,并且在名称旁边没有什么共同之处。
void
主要用于函数声明/定义(作为返回类型或表示“不带参数”)。您永远不可能拥有void
类型的对象。永远。因此很难看出需要找出不存在的对象的大小。 GCC's behavior is nonstandard, and an intentional extension。但是,我相信他们选择了sizeof(void) == 1
,因为C ++标准要求每个对象占用至少一个字节的空间。
void*
表示“指向实际数据的指针,但没有相关的类型信息”。完全可以void*
;而且你会遇到很多。但是,因为忽略了类型信息,所以无法操纵指针。这是设计上的,因为如果你不知道你拥有什么,你真的不知道你能用它做什么。
但是如果你想将内存视为一个字节集合,那么char*
就是这样做的。到处都是char
一个字节。字符串是char*
。如果您觉得这很奇怪,请使用byte*
(您将byte
定义为unsigned char
)。
答案 4 :(得分:1)
我至少可以在第一行看到错误 - 你有sizeof(void),它应该是sizeof(void *),不是吗?
答案 5 :(得分:1)
对于纯粹指向原始数据并将该指针递增一个数据块占用的字节数,我总是使用char *
。然后,一旦我需要将其视为特定的东西,我会重新指向相关数据结构指针。增加void *
在编译器中不可移植。
答案 6 :(得分:1)
void *被很好地识别并用作原始内存的无类型指针。
正确。没有类型也意味着没有大小。
答案 7 :(得分:-3)
correct answer似乎是使用char *
进行指针运算,因为sizeof(char)
始终定义为1,并且是任何平台上最精细的可寻址粒度。< / p>
所以简而言之,没有办法绕过限制,char *
实际上是正确的方法。
Matthias Wandel有right answer但有不同的理由。