1

I am programming Arduino and I would like to use a #define statement in order to set an array of bytes to be passed to the Ethernet.begin() function. At this time I am using the following code and all works as expected:

#define MAC_ARRAY { 0x43, 0xA3, 0xDA, 0x0D, 0xF5, 0xA5 }

void setup() {
  byte mac[] = MAC_ARRAY;

  if (Ethernet.begin(mac) == 0) {
    ...
  }
}

As you can see in the above code, I have to state byte mac[] = MAC_ARRAY; throughout the source code each time I use the MAC_ARRAY value. However I would like to avoid stating that (I think also that "on the long way" there could be memory issues since the mac[] variable is instantiated) and to pass someway the proper MAC_ARRAY directly to the Ethernet.begin() function.

Is it possible? If so, how should I change the #define MAC_ARRAY ... statement?

pnuts
  • 58,317
  • 11
  • 87
  • 139
Backo
  • 18,291
  • 27
  • 103
  • 170
  • No it's not possible to pass "literal" arrays to functions, unless you have a C++11 compatible compiler/standard library and the functions themselves are coded for that using the [`std::initializer_list`](http://en.cppreference.com/w/cpp/utility/initializer_list) class. – Some programmer dude Oct 02 '13 at 10:27
  • Your code is already simple and correct, there's no need to mess with it – M.M Nov 05 '15 at 21:56

1 Answers1

0

as joachim Pileborg already mentioned, if you have a c++11 compatible compiler it is possible to pass an literal array to a function, and the function (Ethernet.begin) has a begin(std::initializer_list) variant.

however, your example is close to a solution. make mac global (const if possible) and remove the define:

uint8_t const mac[] = { 0x43, 0xA3, 0xDA, 0x0D, 0xF5, 0xA5 };
   //^^^^^ -> if begin isn't able to handle const, remove the const here.

void setup() {
  if (Ethernet.begin(mac) == 0) {
    ...
  }
}

this will instatiate mac only once and reuse it (no memory issue).

there are some possibilities, depending on the code:

  1. Ethernet.begin is defined with a reference/pointer as parameter. this would mean your are passing just a reference which is ussaly smaller then 6 byte (sizeof(mac)). and mac is just once stored in memory.

  2. here mac have to be declared const. so the compiler could optimize it and incorporating the value directly into the machines instruction opcodes. therefore you have to compile with optimization-flags on. see here

  3. if both are not a case, then it is still ok, because mac is instantinated still once and will be passed by value (copy) over stack memory.

the best is both... byte const mac and begin(byte const*), so the compiler would decide the best way to spare memory and time.


there is no disadvantage to make it global. a define will result in translated opcode, also maybe global const will (see above case 2) if optimized. but a const will result in one instance also one opcoder (while initializing mac) and the rest in references/aliases to this instance (addressing the value). the behaviour is defined by the implementation of your Ethernet.

Community
  • 1
  • 1
user1810087
  • 5,146
  • 1
  • 41
  • 76
  • You said "this will instatiate mac only once and reuse it (no memory issue)"... what exactly go on memory? those statements consume the same amount of memory (flash, RAM, ...)? and, if any, what are differences at memory level when using `#define` and `const`? – Backo Oct 02 '13 at 10:55
  • Why you put `const` inside `/*` `*/`? – Backo Oct 02 '13 at 12:08
  • because i don't know if Ethernet.begin() is possible to handle const or not. `const if possible` :) – user1810087 Oct 02 '13 at 12:37
  • *BTW*: The `Ethernet.begin()` function seems do not support the `const` statement: the compiler generates the `invalid conversion from 'const byte*' to 'uint8_t*'` error. – Backo Oct 02 '13 at 12:51
  • use uint8_t instead of byte. – user1810087 Oct 02 '13 at 12:51
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/38484/discussion-between-itwasntpete-and-backo) – user1810087 Oct 02 '13 at 12:52
  • If I use `uint8_t const ...` I get the `invalid conversion from 'const uint8_t*' to 'uint8_t*'` error. – Backo Oct 02 '13 at 12:53