在 MSVC 中对 void * 执行指针运算时出错

发布于 2024-09-14 07:07:36 字数 579 浏览 3 评论 0原文

Error    1    error C2036: 'const void *' : unknown size    file.cpp     111

我不跟。 GCC 从不抱怨 void * 指针算术,即使在 -ansi -pedantic -Wall 上也是如此。有什么问题吗?

这是代码-

struct MyStruct {

    const void *buf;    // Pointer to buffer  
    const void *bufpos; // Pointer to current position in buffer

};

...

size_t    someSize_t, anotherSize_t;
MyStruct *myStruct = (MyStruct *) userdata;
...
  if ( (myStruct->bufpos + someSize_t) > 
       (myStruct->buf + anotherSize_t) ) { // Error on this line
     ...
Error    1    error C2036: 'const void *' : unknown size    file.cpp     111

I don't follow. GCC never complains about void * pointer arithmetic, even on -ansi -pedantic -Wall. What's the problem?

Here's the code-

struct MyStruct {

    const void *buf;    // Pointer to buffer  
    const void *bufpos; // Pointer to current position in buffer

};

...

size_t    someSize_t, anotherSize_t;
MyStruct *myStruct = (MyStruct *) userdata;
...
  if ( (myStruct->bufpos + someSize_t) > 
       (myStruct->buf + anotherSize_t) ) { // Error on this line
     ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烂柯人 2024-09-21 07:07:36

您无法对 void * 指针进行指针数学运算。将 oData->bufposoData->anotherConstVoidPtr 转换为编译器知道如何处理的内容。由于您似乎正在寻找大小(大概以字节为单位),因此转换为 char * 应该可以:

if (((char *)oData->bufpos + someSize_t) ...

You can't do pointer math on a void * pointer. Cast oData->bufpos and oData->anotherConstVoidPtr to something the compiler knows how to deal with. Since you seem to be looking for sizes, which are presumably in bytes, casting to char * should work:

if (((char *)oData->bufpos + someSize_t) ...
べ繥欢鉨o。 2024-09-21 07:07:36

上线了:

if ( oData->bufpos ...

bufpos的类型依然是void*。编译器不知道该指针指向什么,因此它会给出该错误。

对于指针算术, void* 没有大小,因此获取偏移量或进行其他指针算术没有意义。如果您想将其偏移多个字节,请将其转换为 char*:

if(((char*)oData->bufpos) + offset ...

在给出更多代码/上下文后进行编辑

如果您可以帮助它,请尝试使用 char* 而不是 void*。 C 地区的人们会知道你在说什么,因为字符是字节,你会省去转换的麻烦。

On the line:

if ( oData->bufpos ...

The type of bufpos is still void*. The compiler doesn't know what that pointer points to, so it gives you that error.

For pointer arithmetic, void* has no size, so taking an offset, or doing other pointer arithmetic doesn't make sense. Cast it to char* if you want to offset it by a number of bytes:

if(((char*)oData->bufpos) + offset ...

Edited after more code/context was given

If you can help it, try to use char* instead of void*. People in C-land will know what you are talking about, because chars are bytes, and you'll save yourself the headache of casting.

小草泠泠 2024-09-21 07:07:36

这确实是旧帖子,但即使 Visual Studio 2022 支持 C11 和 c17,如果您尝试向 void 指针地址添加大小,MSVC 也会返回错误,但对于 GCC 来说这完全没问题。

void* array_get_ref(const arr_t* this, size_t index)
{
    return this->buffer + (index * this->item_size);
}

要解决 MSVC 上的问题,您需要将 void 指针强制转换为 char* ,如下所示,它将正常工作。

void* array_get_ref(const arr_t* this, size_t index)
{
    return (char*)this->buffer + (index * this->item_size);
}

如果我们考虑一下:任何指针都给我们内存地址,因此在这种情况下是数组的开始,我们只需要添加字节偏移量、索引* item_size,它们在创建数组时存储到结构体中。 (在这种情况下,类型转换什么也不做,只是欺骗了 MSVC 编译器)

It is really old post but even Visual Studio 2022 supports C11 and c17 MSVC is returning error if you try to add size to void pointer address but for GCC that is totally fine.

void* array_get_ref(const arr_t* this, size_t index)
{
    return this->buffer + (index * this->item_size);
}

To solve problem on MSVC you need to cast void pointer to for example char* like this and it will work fine.

void* array_get_ref(const arr_t* this, size_t index)
{
    return (char*)this->buffer + (index * this->item_size);
}

If we think it about: any pointer is giving us memory address, so begin of array in this case and we just need to add byte offset , index * item_size which is stored to struct when we created array. (casting does nothing in this case just tricks MSVC compiler)

红玫瑰 2024-09-21 07:07:36

$3.9.1/9-
void 类型有一组空值。 void 类型是不完整类型,无法完成。它用作不返回值的函数的返回类型。任何表达式都可以显式转换为类型 cv void (5.4)。 void 类型的表达式只能用作表达式语句 (6.2)、逗号表达式 (5.18) 的操作数、?: (5.16) 的第二个或第三个操作数、typeid 的操作数或返回类型为 void 的函数的返回语句 (6.6.3) 中的表达式。

我怀疑“void”的不当使用超出了标准的允许范围。

$3.9.1/9-
The void type has an empty set of values. The void type is an incomplete type that cannot be completed. It is used as the return type for functions that do not return a value. Any expression can be explicitly converted to type cv void (5.4). An expression of type void shall be used only as an expression statement (6.2), as an operand of a comma expression (5.18), as a second or third operand of ?: (5.16), as the operand of typeid, or as the expression in a return statement (6.6.3) for a function with the return type void.

I suspect an improper use of 'void' beyond what is allowed by the Standard.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文