With std::byte standardized, when do we use a void* and when a byte*?

Viewed 5375

C++17 will include std::byte, a type for one atomically-addressable unit of memory, having 8 bits on typical computers.

Before this standardization, there is already a bit of dilemma when pointing into "raw" memory - between using char*/unsigned char* on one hand or void * on the other. Now, one of reasons for prefering void * is removed - std::byte does not have the same connotations as a char; it's about raw memory, not characters.

So, my question is: What is a good rule of thumb, for the days of std::byte, regarding when to prefer it over void * and when it's the other way around?


Of course when you're dealing with old code, or C code, you're constrained by what it accepts; I mostly mean new code where you get to choose all the types.

4 Answers

std::byte is not just about "raw memory", it is byte-addressable raw memory with bitwise operations defined for it.

You should not use std::byte to just blindly replace void*. void* retains its use. void* means to the handling code "this is a block of data but I don't know what this data is, nor do I know how to operate on it.

Use std::byte when you need byte address of the memory block and only bitwise operations defined for operating on that data.

std::byte does not have regular basic math operations defined, such as operator+, operator- or operator*. That's right, the following code is illegal:

std::byte a{0b11},b{0b11000};
std::byte c = a+b; // fails, operator+ not defined for std::byte

In other words, use void* when it is not the handling codes business the contents.

std::byte Example

Like I said above, all you can do on a std::byte are the bitwise operations like |, & and ~. An example of the use of std::byte follows, note you need a C++17 compiler to compile this example, there is one here but you must select C++17 from the dropdown at the top right

#include <iostream>
#include <cstddef>
#include <bitset>

using namespace std;

void print(const byte& b)
{
  bitset<8> p( to_integer<int>( b ) );
  cout << p << endl;
}

int main()
{
  byte a{0b11},b{0b11000};
  byte c=a|b;
  //byte d = a+b; // fails
  print(c);
  return 0;
}
Related