2

I have an issue with C++ and creating a reference byte[].

In C# my method is:

public static void SetBitAt(ref byte[] Buffer, int Pos, int Bit, bool Value)
    {
        byte[] Mask = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
        if (Bit < 0) Bit = 0;
        if (Bit > 7) Bit = 7;

        if (Value)
            Buffer[Pos] = (byte)(Buffer[Pos] | Mask[Bit]);
        else
            Buffer[Pos] = (byte)(Buffer[Pos] & ~Mask[Bit]);
    }

I want to translate it to C++, but I can't get the refworking for C++. I saw something about the & symbol and I tried something like this:

void SetBitAt(byte& buffer[], int Pos, int Bit, bool Value)
{
    byte Mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
    if (Bit < 0) Bit = 0;
    if (Bit > 7) Bit = 7;

    if (Value)
    {
        buffer[Pos] = (byte)(buffer[Pos] | Mask[Bit]);
    }
    else
    {
        buffer[Pos] = (byte)(buffer[Pos] & ~Mask[Bit]);
    }
}

but then I get the Error:

'buffer': arrays of references are illegal.

So how can I change my C++ code to work with a reference array?

EDIT: I use this method for setting a buffer, but it doesn't change when I use this method.

other class:

buffer = ReadDB(2);          //Read the values in the DataBlock
SetBitAt(buffer, 0,0 true);  //Set bit 0,0 to 1(true)
WriteDB(2, buffer);          //Write the values to the Datablock

but the buffer doesn't change. its the same value.

Bart
  • 647
  • 1
  • 8
  • 26

4 Answers4

4

If you want to pass array by reference, you should

void SetBitAt(byte (buffer&)[10], int Pos, int Bit, bool Value)

But in your case, you don't need that, just

void SetBitAt(byte buffer[], int Pos, int Bit, bool Value)

Note in this case array will decay to pointer (i.e. byte*), that means the size of array won't be reserved as pass by reference would.

songyuanyao
  • 147,421
  • 15
  • 261
  • 354
  • check my question, ive added some extra information where I use this method for. – Bart Nov 13 '15 at 10:11
  • Bart, this answer is correct. In C and C++, an array is passed as a pointer, so elements can be referenced. Since all your code is doing is referencing elements, no more is needed. – Peter Nov 13 '15 at 10:17
  • @Bart: You've now gone from the original question into debug-help-me mode, but you're missing the [MCVE](https://stackoverflow.com/help/mcve). We've answered the question correctly and you might simply need to do further debugging of your logic. – code_dredd Nov 13 '15 at 10:17
  • @ray yep you are right, I'll just create a new question for my next problem – Bart Nov 13 '15 at 10:18
  • @Bart Could you provide a [MCVE](https://stackoverflow.com/help/mcve) for it? I've tried one [here](http://rextester.com/TDQWI55137), please check it. You might need to check whether `SetBitAt()` set the value correctly. – songyuanyao Nov 13 '15 at 10:19
  • @songyuanyao I tested it myself and it seems the buffer does change. Thanks for your time and help! – Bart Nov 13 '15 at 10:46
1

'buffer': arrays of references are illegal.

This is due to operator precedence. Saying byte &buffer[] is an array of references, while saying byte (&buffer)[size] is a reference to an array.

See C++ pass an array by reference for more details.

So how can I change my C++ code to work with a reference array?

When passing your array as a function argument, you should drop & symbol. You can still modify the contents of your array because the array's address is passed instead.

Assuming you have a typedef of char to byte, your function signature should look like this:

void SetBitAt(byte buffer[], int Pos, int Bit, bool Value) { ... }

Note that the above is equivalent to passing a pointer:

void SetBitAt(byte *buffer, int Pos, int Bit, bool Value) { ... }

Modifying the contents of your array is still a matter of saying buffer[Pos] = // some value;

This post on What is array decaying? should be useful.

code_dredd
  • 5,368
  • 1
  • 21
  • 48
0

Shouldn't it simply be like this:

void SetBitAt(byte buffer[], int Pos, int Bit, bool Value)
{
    byte Mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
    if (Bit < 0) Bit = 0;
    if (Bit > 7) Bit = 7;

    if (Value)
    {
        buffer[Pos] = (byte)(buffer[Pos] | Mask[Bit]);
    }
    else
    {
        buffer[Pos] = (byte)(buffer[Pos] & ~Mask[Bit]);
    }
}

In this way, buffer is passed as a pointer, and buffer[Pos] references to the Pos-th element of buffer. It is plain C, but it should work.

SimoneLazzaris
  • 289
  • 1
  • 7
  • I did that, but then it doesn't change my buffer, see my edited question for more info. – Bart Nov 13 '15 at 10:13
0

You can pass it simply by address as:

void SetBitAt(byte* buffer, int Pos, int Bit, bool Value) { ... }

or simply as:

void SetBitAt(byte buffer[], int Pos, int Bit, bool Value) { ... }

Either one will tell the compiler that byte pointer is passed to function, althrough with second header you omit pointer arithmetics ;)

Konrad 'Zegis'
  • 9,803
  • 1
  • 12
  • 18