如何摆脱-Wpointer-arith

时间:2019-03-20 14:21:57

标签: c++ pointers void-pointers pointer-to-pointer

此代码:

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);
  ~~~~~~~~^~~~~~~~~~

我知道它应该需要取消引用和强制转换,但是我无法确切地知道如何正确地做到这一点。

谢谢互联网! :)

2 个答案:

答案 0 :(得分:2)

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

但是考虑到您尝试将指针增加sizeof(unsigned int),如果*buffer指向unsigned int数组的元素,并且您尝试增加指针是有意义的到下一个兄弟姐妹。

正确的方法是:

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

另一方面,如果指向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;
}

答案 1 :(得分:1)

好吧,您要递增void指针。
void的大小是多少?

在将其递增之前,应将指针强制转换为正确的类型。
sizeof给出字节大小,因此正确的类型应为uint8_tunsigned char

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