Use char * or void * or something else for byte fields in C ++?

I have several byte fields that contain a field of different numeric types. The pointers to these fields are then passed and stored as members in other classes.

Should I use char*

or void*

for pointer type?

Currently, I only see one benefit for char*

: you can't play void*

. This is not a problem when reading the value outside of the field, as I have to somehow insert into the appropriate pointer type. In case I want to make a regular copy of a byte field, I would first need to do void*

in char*

, so it would be easier to save it as char*

.

Or are there any reasons against using it char*

?

Generally, I would prefer to stay as low as possible since I have to pass fields to other low level interfaces.

+3


source to share


3 answers


Using char * for blocks of memory is "easy to use" (eb byte by byte), but very bad for reading and understanding the code (you still see it in different APIs).

If your data is just a block of memory, then void * is better.

Only if your data is an array of a certain type (char, int, uint8_t, some struct, ...) then use a pointer of that type.



If you need to treat the structure as "byte data" (for example, to compute a hash), you can internally treat it as "char *" (or uint8_t * or uint_32_t * or whatever you want). However, the public API should still be invalid * unless you require a specific memory layout.

The point is, if you have an API that uses void *, you can point to it with any type of pointer (which is the hash point). However, you always need a reinterpret_cast if you are using char *.

+5


source


Usage char

can cause some problems - it all depends on how you want to handle the values ​​stored behind such pointers.

The problem is what is byte

usually interpreted as an unsigned value. For example: UTF-8 encoding. It creates a sequence of bytes that can have different meanings depending on the coded point of the code . If we were to use a signed type, we would have to distinguish the unsigned value so that it can validate its values ​​correctly (code points exceeding U+007F

are always translated into a byte sequence in which they all have a sign bit equal to 1).

But whether signed char

or not is implementation dependent. In fact, the C ++ standard defines three different types:

  • char
  • signed char
  • unsigned char

If you have enabled #include <limits.h>

, you can see CHAR_MIN

:

  • if 0 is specified, char

    unsigned
  • if some negative value is defined (usually -128) the char is signed


So what does this all mean?

You should store bytes in such a way that you can read / write your values ​​without additional checks. You probably want your bytes to be unsigned values, so define a new type (like many high-level languages ):

typedef unsigned char Byte;

      

And then define your pointers as:

Byte* data_pointer;

      

Then, if your functions expect "void *" or "Byte", nothing needs to be done. However, if they expect pointers to a specific numeric type ( int

, float

etc.), you will need reinterpret_cast

them.

+2


source


Very simple and low resource is a simple union of typed pointers as I understand that the actual type is the context that makes it fit.

To be at the other end with execution dynamics, there is Boost :: Any

0


source







All Articles