Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 979
einpoklum Avatar asked Aug 01 '17 10:08

einpoklum


People also ask

How do you define a byte in C++?

@Ben: The C and C++ standards unambiguously define a "byte" as the size of a char , which is at least 8 bits. The term "byte" may be defined differently in other contexts, but when discussing C or C++ it's better to stick to the standard's definition.

What is the point of std :: byte?

std::byte is a distinct type that implements the concept of byte as specified in the C++ language definition. Like char and unsigned char, it can be used to access raw memory occupied by other objects (object representation), but unlike those types, it is not a character type and is not an arithmetic type.


1 Answers

(This is a potential rule of thumb which comes off the top of my head, not condoned by anyone.)

Rule of thumb: When to use which kind of pointer?

  • Use char * for sequences of textual characters, not anything else.
  • Use void * in type-erasure scenarios, i.e. when the pointed-to data is typed, but for some reason a typed pointer must not be used or it cannot be determined whether it's typed or not.
  • Use byte * for raw memory for which there is no indication of it holding any typed data.

An exception to the above:

  • Also use void */unsigned char */char * when older code; or when non-C++ code forces you and you would otherwise use byte *. But when doing this, you could still wrap such use with a byte *-based interface, thus not exposing this state of affairs to the rest of your C++ code.

Examples

void * my_custom_malloc(size_t size) - wrong
byte * my_custom_malloc(size_t size) - right

struct buffer_t { byte* data; size_t length; my_type_t data_type; } - wrong
struct buffer_t { void* data; size_t length; my_type_t data_type; } - right

like image 54
einpoklum Avatar answered Sep 30 '22 15:09

einpoklum