In C (using gcc) I can declare a variable length struct as below:
typedef struct ProtocolFrame
{
uint8_t op;
uint32_t address;
uint16_t size;
uint8_t payload[0];
} ProtocolFrame;
then I can alloc different frame:
ProtocolFrame *frA;
ProtocolFrame *frB;
frA = malloc(sizeof(ProtocolFrame) + 50);
frB = malloc(sizeof(ProtocolFrame));
In this example frA has a payload field as big as 50 bytes, and frB has no payload
Can I do the same thing in C++ using the new operator?
Yes, you can create arrays of any type with length zero.
Zero length arrays are described as being an IBM Extension enabled by the *EXTENDED compiler option (aka -qlanglvl=extended when using ixlc). According to the compiler output *EXTENDED is in effect (which is why char d[]; is being accepted as a flexible array).
If you have a function that takes an array, and you want to give it an array with nothing in it, you pass an zero-length array. If you read an array from an external source, and it happens to not have any items, you'll get an zero-length array.
Some Windows structures are variable-sized, beginning with a fixed header, followed by a variable-sized array. When these structures are declared, they often declare an array of size 1 where the variable-sized array should be.
template<size_t s>
struct ProtocolFrame
{
uint8_t op;
uint32_t address;
uint16_t size;
uint8_t payload[s];
} ProtocolFrame;
// specialize for no payload
template<>
struct ProtocolFrame<0>
{
uint8_t op;
uint32_t address;
uint16_t size;
} ProtocolFrame;
ProtocolFrame<50> *frA = new ProtocolFrame<50>;
ProtocolFrame<0> *frB = new ProtocolFrame<0>;
To decide what is the size at runtime you could use placement-new operator in cooperation with std::malloc
:
void *buffer = std::malloc(sizeof(ProtocolFrame)+50);
ProtocolFrame *frA = new (buffer) ProtocolFrame;
You can read also this article on the codeproject.com which is contain the full sample.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With