What you want will not work the way you think: in C++ (just like in C), arrays and pointers are almost the same, and the compiler won't be able to make a distinction between
void f(int* array)
and
void f(int array[])
In particular, inside f()
the compiler won't be able to know the actual size of array
: for the compiler sizeof array
will always be the same as sizeof(int*)
, i.e. just the size of a pointer, always 2 bytes on Arduino UNO, whatever type it points to.
If you want your foreach
macro to work correctly, you have to pass it the actual array count of items as an additional argument:
#define foreach(item, array, size) \
for(int keep = 1, \
count = 0;\
keep && count != size; \
keep = !keep, count++) \
for(item = (array) + count; keep; keep = !keep)
And also pass the count of items in Words
:
void Words(int w[], size_t size) {
foreach(int *v, w, size) {
Serial.println(*v);
delay(500);
}
}
In loop()
you can use sizeof example
, because the compiler knows what its size is, from its initialization (an array of 5 integers, i.e. 10 bytes):
void loop() {
Words(example, sizeof example / sizeof example[0]);
}
You could even define a macro to compute the count of items in an array:
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
It will work as long as you use it with an argument that is completely known by the compiler:
void loop() {
Words(example, ARRAY_SIZE(example));
}
Important comments on your original code
You mentioned that you want to "save space", but defining a macro will not help in this regard, as a macro is NOT a function, hence its binary code will be repeated everywhere it is used. It can just help make your source code shorter and possibly clearer.
The way you defined your macro seems weird and overly complex to me: why use 2 for
loops when you need only one?
It would have been possible to define it in a simpler way, for example:
#define foreach(type, var, array, size) \
for(type* var = array; var != array + size; var++)
It would be used as follows:
void Words(int w[], size_t size) {
foreach(int, v, w, size) {
Serial.println(*v);
delay(500);
}
}
Using C++ templates may probably help too, but this is an advanced topic. I'd recommend reading first some good book about C++ before digging into templates.
sizeof array
which can not be correct whenforeach
is called fromWords(int v[])
function. If you putWords
code directly inloop
then it should work: did you check that?