5

I need to hard code 8 byte addresses into char arrays of length 8. This must be done many places in my code (in function scope), so I have tried to come up with a one-liner. The following works perfectly in C when compiling with gcc.

char a[8];

void cpaddr(char target[], char *source) {
    int i;
    for (i=0; i<8; i++)
        target[i] = source[i];
}

int main() {
    char b[] = {0x00, 0x10, 0xFF, 0xCA, 0x00, 0x00, 0xA2, 0x7D};
    cpaddr(a, b);

    // line below does not compile with Arduino IDE
    cpaddr(a, (char[]) {0x00, 0x10, 0xFF, 0xCA, 0x00, 0x00, 0xA2, 0x7D});
}

When compiling on Arduino the last line, which is the one-liner I was aiming for, does not compile. It gives:

/home/bob/Desktop/ate/Ate.ino: In function 'int main()':
Ate:101: error: taking address of temporary array
cpaddr(a, (char[]) {0x00, 0x10, 0xFF, 0xCA, 0x00, 0x00, 0xA2, 0x7D});
^
exit status 1
taking address of temporary array

What is the problem here, that apparently is not a problem with gcc?

How do I fix it?

VE7JRO
  • 2,515
  • 19
  • 27
  • 29
Mads Skjern
  • 1,145
  • 3
  • 13
  • 23

3 Answers3

4

It is quite right, using that kind of syntax is not allowed. It's a bit of a pain, but it's ok since there is an alternative method - kind of a "trick" if you will.

That trick is to use a string, not an array. After all, a string is just an array, it's just handled slightly differently by the compiler.

Instead of using {...} use "..." and use the hexadecimal character escape sequence \xNN, such as:

cpaddr(a, "\x00\x10\xFF\xCA\x00\x00\xA2\x7D");

You could even lose your custom function and use a standard library function - memcpy():

memcpy(a, "\x00\x10\xFF\xCA\x00\x00\xA2\x7D", 8);

On the 8-bit AVRs you can save RAM by using the progmem variant and the F() macro:

memcpy_P(a, F("\x00\x10\xFF\xCA\x00\x00\xA2\x7D"), 8);
Majenko
  • 105,851
  • 5
  • 82
  • 139
1

See Using array init list as temporary in C++11?

You can solve it by using const. This compiles:

char a[8];

void cpaddr(char target[], const byte *source) {
    int i;
    for (i=0; i<8; i++)
        target[i] = source[i];
}

int main() {
    byte b[] = {0x00, 0x10, 0xFF, 0xCA, 0x00, 0x00, 0xA2, 0x7D};
    cpaddr(a, b);
    cpaddr(a, (const byte[]) {0x00, 0x10, 0xFF, 0xCA, 0x00, 0x00, 0xA2, 0x7D});
}

Note I had to change your array from char to byte because I was getting (valid) warnings that things like 0xCA don't fit into a char.

Nick Gammon
  • 38,901
  • 13
  • 69
  • 125
0

How do I fix it?

"Char []" shouldn't compile under c. It is just invalid.

You can use string, cast to char * . or just another pointer as you did already.

dannyf
  • 2,813
  • 11
  • 13