2

Is there any simple way to have a custom width variable? I know you can

void* foo = new unsigned char[ 40 ];
// foo points to some var that needs 40 bytes of data to contain it

and then cast & dereference foo and modify it based on the size of the type you cast it to.

I was wondering if there was something more genius, perhaps using unions.

union
{
public:
    unsigned int data; // how you want to treat the data based on this var's datatype
private:
    unsigned char reserved[ 40 ]; // actual size of data
} foo;

foo.data = 20u; // unfortunately, this only affects 8* bytes of the full 40 reserved...
  • You could just use a class – Fureeish Oct 11 '18 at 05:36
  • I just wonder how "this only affects 8* bytes" works. – Xiaofeng Oct 11 '18 at 05:41
  • 1
    can you explain a bit more what you want and why you want it? cuz parts of your question might lead to [`alignas`](https://en.cppreference.com/w/cpp/language/alignas) but its not clear – kmdreko Oct 11 '18 at 05:42
  • An object **is** the bytes that make up it's representation. It cannot change size. Are you asking about `reinterpret_cast`ing the address of a T to a `char *` (+ a `sizeof T` length) and using those bytes? – Caleth Oct 11 '18 at 08:35
  • What you want to achieve?It sounds a bit that you think in python or some other scripting language, where variables can be "assigned" to any size/data type ever and ever again. But c++ is a strictly typed language. So there is also a other "mindset" to write programs. For changing types see std::variant or std::any. If you change size dynamic, use container classes like std::vector or maybe std::string. You also may use a combination like std::vector. But the first question still is: What you really need! Unions, also std::variant, always uses the memory of the biggest used type. – Klaus Oct 11 '18 at 08:41

2 Answers2

0

Well, this statement in your question:

void* foo = new unsigned char[ 40 ];

is allocating 40 bytes of unsigned char type on the free-store (or heap) i.e. dynamic memory allocation. You can simply avoid pointer operations e.g. casting, increment, decrement, de-reference, etc. by using an array on stack like this:

unsigned char foo[ 40 ];

That is the case when you already know the size e.g. 40 in your question.

So, there are two types of arrays according to lengths: fixed and variable. Fixed-length that you know at compile-time; and, variable-length that you get at run-time. And, from your question, the term "custom" might be referring to "variable-length arrays".


You cannot have a variable-length array on stack in standard C++ so you have to allocate it on free-store using new[] and de-allocate after use using delete[]. Though, some compiler extensions also allow variable-length arrays e.g. GCC (See: C++ : Variable Length Array).

So, if you have an array size that you don't know already then the dynamic memory allocation is way to go.

Or, you can simply use an STL container such as std::vector. It'll handle all the memory management stuff under the hood. And, you can simply start writing your business logic right away instead of spending time on memory management. And, for static fixed-length arrays, you ought to use std::array with all the good stuff that come with it.

And, if you really want to do memory management stuff yourself, you ought to look at std::unqiue_ptr and std::shared_ptr along with std::make_unique and std::make_shared wherever applicable depending on your use-cases. That would make life easy by enforcing RAII.

As you're working with raw bytes (guessed it from unsigned char), you ought to use std::byte if you can have a C++17-enabled compiler.


Relevant material:


Hope that helps!
If there is more to your use-case, kindly add that detail in your question so that the answer could be more relevant and aligned to that specific use-case.

Azeem
  • 11,148
  • 4
  • 27
  • 40
0

From high to low level:

bobah
  • 18,364
  • 2
  • 37
  • 70