void时指针算法的大小未知

时间:2009-12-08 03:18:54

标签: c visual-studio gcc void-pointers pointer-arithmetic

在Visual Studio C ++版本9(以及可能还有其他版本)中,代码如下:

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

生成these errors

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

此代码适用于GCC,它处理sizeof(void) as 1

是否存在某种解决此限制的方法,因为为了指针运算而明确地向char *进行强制转换会增加混淆(void *被很好地识别并用作指向原始内存的无类型指针。)< / p>

Update0

  • 请注意,我很清楚 存在标准。
  • 希望做原始指针 算术。
  • 我带sizeof(void)来 表明我很清楚这一事实 它不是1 问题的原因。
  • 代码 例子只是为了证明什么 需要生成错误。
  • 我知道这不是使用void的“正常”方式,但这是C,这些都会发生。
  • 是的,人们需要在低级别这样做。我不是在追求原因,我是在追求如何。如果您想知道原因,请查看一些内核源代码或友好的glibc。

UPDATE1

这个问题似乎引起了很大的困惑。问题不在于为什么 sizeof(void) == 1不是标准的,而是在不是标准时该做什么。

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

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

8 个答案:

答案 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 Wandelright answer但有不同的理由。