void时指针算法未知大小

在Visual Studio C ++版本9(也可能是其他版本)中,代码如下:

int a = sizeof(void); void const *b = static_cast("hello world"); b += 6; 

生成这些 错误 :

 error C2070: 'void': illegal sizeof operand error C2036: 'const void *' : unknown size 

此代码在GCC下工作,它将sizeof(void)视为1

有没有办法绕过这个限制,因为为了指针运算而显式地转换为char *会增加混淆( void *被很好地识别并用作指向原始内存的无类型指针)。

Update0

  • 请注意,我很清楚标准的存在。
  • 想做原始指针算术。
  • 我把sizeof(void)表示我很清楚它不是1的原因是问题的原因。
  • 代码示例仅用于演示生成错误所需的内容。
  • 我知道这不是使用void的“正常”方式,但这是C,这些事情发生了。
  • 是的,人们需要在低级别这样做。 我不是在追求原因,我是在追求如何。 如果你想知道原因,请查看一些内核源代码或友好的glibc。

UPDATE1

看来这个问题引起了很大的混乱。 问题不在于为什么 sizeof(void) == 1不是标准的,而是什么时候不做。

在要进行单字节指针运算的情况下,事实certificate,转换为char *是正确的答案,不是因为*(void *)没有大小,而是因为标准实际上保证*(char *)永远是1 。 因此,为了原始指针算法的目的, char *的使用总是正确的,并且与具有GCC扩展的void *一致。

为了进一步强调这一点, void *是指向无类型内存的指针的正确选择,而char *是用于转换为原始指针算法的正确类型。

从技术上讲,增加一个指针可以通过它指向的任何大小来增加它。 无效点无所谓,因此大小未知。

对于某些编译器来说,它是一个让你增加void指针的精确性。

转换很烦人,因为你必须将它转换为另一个指针,然后返回,或做一些尴尬的事情,如(*(char *)&voidptr) += 6

就个人而言,我只是为了算术而将它声明为char *

在C语言中, sizeof不能应用于不完整类型。 void是一个不完整的类型,这就是为什么你不能将它用作sizeof操作数。

C中也不支持void *指针的指针算法。为了与指针算法一起使用,指针必须指向对象类型,而void不是。

GCC允许两者作为奇怪的语言扩展。

void *意味着“指向未知的指针”

因此,未定义向void指针添加6,因为您要求编译器将指针推进“6个未知对象的大小”。

你不应该这样做。

这里有两个不同的问题。 第一个是void ,第二个是void* 。 它们是不同的类型,并且在名称旁边几乎没有共同之处。

void主要用于函数声明/定义(作为返回类型或表示“不带参数”)。 你永远不可能有一个void类型的对象。 永远。 因此很难看出需要找出不存在的对象的大小。 海湾合作委员会的行为是非标准的,是故意的延伸 。 但是,我相信他们选择了sizeof(void) == 1因为C ++标准要求每个对象占用至少一个字节的空间。

void*表示“指向实际数据的指针,但没有相关的类型信息”。 完全可能void* ; 而且你会遇到很多。 但是,因为忽略了类型信息,所以无法操纵指针。 这是设计,因为如果你不知道你有什么,你真的不知道你可以用它做什么。

但是如果你想将内存视为一个字节集合,那么char*会这样做。 char是一个字节,无处不在。 字符串是char* 。 如果您发现这很奇怪,请使用byte* (其中您将byte定义为unsigned char类的东西)。

我至少可以在第一行看到错误 – 你有sizeof(void),它应该是sizeof(void *),不是吗?

对于纯粹指向原始数据并将该指针递增一个数据块占用的字节数,我总是使用char * 。 然后,一旦我需要将其视为特定的东西,我就会重新指向相关数据结构指针。 增加void *在编译器中不可移植。

void *被很好地识别并用作原始内存的无类型指针。

正确。 没有类型意味着没有大小。

看起来正确的答案是使用char *作为指针算法,因为sizeof(char)总是被定义为1,并且在任何平台上都是最好的可寻址粒度。

简而言之,没有办法绕过限制, char *实际上是正确的方法。

马蒂亚斯·万德尔有正确的答案,但有不同的理由。