Как избавиться от -Wpointer-arith - PullRequest
0 голосов
/ 20 марта 2019

Этот код:

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 ]

2 голосов
/ 20 марта 2019

Невозможно проверить, что это правильно, если вы не показываете, на что указывает указатель.

Но, учитывая, что вы пытаетесь увеличить указатель на 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 голос
/ 20 марта 2019

Ну, вы увеличиваете указатель void.
Каков размер void ??

Вы должны привести указатель к правильному типу, прежде чем увеличивать его.
sizeof дает размер в байтах, поэтому правильный тип должен быть uint8_t или unsigned char.

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

...