如何摆脱 -Wpointer-arith

How to get rid of -Wpointer-arith

此代码:

void Pack::packUInteger(void **buffer, unsigned int payload){
    memcpy(*buffer, &payload, sizeof(unsigned int));
    *buffer += sizeof(unsigned int);    
}

产生这个警告,我想在不告诉编译器忽略它的情况下摆脱它:

src/messaging/Pack.cpp: In static member function ‘static void Pack::packUInteger(void**, unsigned int)’:
src/messaging/Pack.cpp:33:10: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
  *buffer += sizeof(unsigned int);
  ~~~~~~~~^~~~~~~~~~

我知道应该需要取消引用和强制转换,但我不知道如何正确执行。

感谢网络! :)

好吧,你正在增加一个 void 指针。
void的大小是多少??

您应该在递增之前将指针转换为正确的类型。
sizeof 以字节为单位给出大小,因此正确的类型应该是 uint8_tunsigned char.

*buffer = (uint8_t*)(*buffer) + sizeof(unsigned int);

除非您显示指针指向的位置,否则无法验证这是正确的。

但是鉴于您尝试将指针递增 sizeof(unsigned int),如果 *buffer 指向 unsigned int 数组的元素并且您尝试递增指向下一个兄弟的指针。

正确的做法是:

auto ptr = static_cast<unsigned*>(*buffer);
*buffer = ptr + 1;

另一方面,如果 if 指向原始存储,例如 std::byte,正确的方法是:

auto ptr = static_cast<std::byte*>(*buffer);
*buffer = ptr + sizeof payload;

而不是使用 void**,我建议改为:

template <class T>
std::byte* pack(std::byte* buffer, T payload) {
    static_assert(std::is_trivially_copyable_v<T>);
    std::memcpy(buffer, std::addressof(payload), sizeof payload);
    return buffer + sizeof payload;
}