Declare Array using #define

Hi everyone,
Can I declare static array using #define preprocessor ?
maybe something like this:

#define myArray[5] {1,2,3,4,5} 

why not simply?

int myArray[5] {1,2,3,4,5};
1 Like

No you can't

think of #define as textual replacement, like if you were doing a find and replace in a word editor.

there is no good reason to use #define for a constant, unless you want to use conditional compilation like #ifdef compiler directives. use

const byte myArray[5] = {1,2,3,4,5};

then you tell the compiler about the type of the data (byte, int, float, ...), if it's const or not etc...

2 Likes

Thank you for your reply,
I found out many tricks about #define like define functions and mathematical operations, so I can say that I'm sure there is a method to #define an array, just I don't know the syntax.

take a look at this example:

#define ADDRESS(n)      (50 + n)

it's similar to be an array, just I want to define specific items instead of an equation.

to reduce program space ..

there's still code for each #define. somewhere in the code there will be "ADDRESS(n)" that will be replaced by "(50+n)".

i've seen #defines that are half of page long. sub-functions would save space. inline() functions are more "best practice", don't save any space but have more type checking (an original used for the C++ compiler at Bell Labs)

it’s not… it’s s macro with one parameter n

If you write ADDRESS(10) in your code, the preprocessor will replace that textually by (50 + 10)

You could do #define createArray(n) const int anArray[n] but what’s this good for? (You could even have the array name as a parameter)

Just don’t and it does not save program space.

define may reduce the amount of text in the sketch, but will not reduce the size of the compiled code (except for use in conditional compilation). The compiler already optimizes away any variables that it can determine are constant or unneeded.

what i'm going to do is declare an array of pins:
const byte relayPins[5]= {A0,A1,A2,A3,A4};

I think there should be another method to declare it without occupy a space of memory

Why would you think that? If you have const arrays and access with const index the optimizer will likely just replace the value. It might even unroll short loops so there would be no SRAM for the array. The challenge is not in the definition but in the access. If you want dynamic access to the data then you need to have the data in some sort of memory

You can store it in flash (PROGMEM) or eeprom and go read it dynamically if you don’t want SRAM

This forum continues to prove that a little knowledge is a dangerous thing.

1 Like

wouldn't the following be compact

    for (unsigned n = 0; n < sizeof(relayPins); n++)  {
        digitalWrite (relayPins [n], Off);
        pinMode      (relayPins [n], OUTPUT);
    }

or do you think the following is better

    digitalWrite (A0, Off);
    pinMode      (A0, OUTPUT);

    digitalWrite (A1, Off);
    pinMode      (A1, OUTPUT);

    digitalWrite (A2, Off);
    pinMode      (A2, OUTPUT);

    digitalWrite (A3, Off);
    pinMode      (A3, OUTPUT);

    digitalWrite (A4, Off);
    pinMode      (A4, OUTPUT);

one difference is the former requires 5 bytes of RAM while the other consumes more PROGMEM (on an Arduino)

You are not reducing anything. It gives you false impression because you type less but 1. defines make code difficult to read 2. when they are preprocessed they fill your program with all the code you thought you reduced. False economy.

You could do it like this:

#define myArray(x) (((x)==0) ? A0 : ((x)==1) ? A1 : ((x)==2) ? A2 :((x)==3) ? A3 : ((x)==4) ? A4 : 0) )

That would mean the expression 'x' would have to be evaluated as many as 5 times.

The critical understanding here is -
#define is one of many pre-processor directives…
They are used to simplify, annotate or prepare for conditional compilation.

They do not affect what’s happening at ‘run-time’. That’s all been decided earlier, when the code and initialised variables are ‘compiled’ and uploaded to the chip.

Thank you all, I'll use const byte instead

If you want to save RAM, use PROGMEM.

I think that in order to avoid the data arrage and hence SRAM usage associated with it on something like the AVR, you must also declare it static.
This ensures that the if the current module does not actually need the array, the compiler does not have to keep the array around for any other modules that might get linked in that might access it.

However, with today's linker optimizations, the linker might still catch that lack of references to the array and remove it at that point.

--- bill

"static" has nothing to do with RAM usage, or lack thereof. It is a scope modifier - i.e. - is modifies WHERE the variable is "visible". "const" tells the compiler a variable cannot be modified, hence it need not be kept in RAM.

But if the x parameter is a constant, then the evaluation(s) happen at compile time and optimized down to the individual desired element.