Declaration of variables and constants

In many sketches , pins of arduino are declared using "int pin=x" . Why not using "#define pin x" which does not use ram space because it is used only by the compiler. Declaring it like an int uses ram like any other variable.

It's not just an Arduino thing. It's a C thing.

define substitutes in a nonvariable way. Unless you manually change it in the source, that definition will always stay the same (a "dictionary" definition, if you will).

It's not just an Arduino thing.  It's a C thing.

It's an Arduino thing. The pin number is absolutely a compile-time constant and the convention for this sort of thing in C is to use #define as the O/P says. There is no good reason why int variables are used for pin numbers in so many samples and sketches. In my opinion it is is a bad habit. There may be good reasons for a pin number to be in a variable, but few that it should not be in a char or uint8_t -- so even the choice of variable type in the examples is rotten.

The thing is that Arduino is meant to be accessible to folks that are not programmers -- if if you read through these forums, you'll see that it hits that mark quite solidly. So ideas that are not strictly necessary to make a simple program work get swept under the rug. CPP macros are a more complicated animal than variable assignment that folks know from Javascript or BASIC, and so that's the simplest way to do what needs doing without scaring anyone.

Ah, m'bad. I read the OP as "why use int variables at all".

In that case, no, I don't have any clue. I don't do that anyway; it just seemed redundant from the get-go.

There are other common arduino practices that kind of go against C best practices. The most common I notice is that typical arduino sketches utilize more global variables, where they probably should be used as local variables if they are only used within a single function. I'm pretty guilty of this myself, as I find it easier to just define all the variables I'm planning on needing at the start of the sketch design. The small size of most sketches lends itself to this practice and as I said while I understand the advantages of proper scoping of variables, the temptation of making most everything global initially seems to work OK for these small applications.

So am I practicing evil here? At least I've haven't resorted to using a goto statement yet, or needed to 'reset' my sketch on the run. :D


You know I never thought about this, but you are right. It is probably a good practice to use #define instead of a variable for single I/O pins. Except in one case: when you want to define an array of I/O pins.

A lot of projects use LEDs and animations. Generally it is helpful to have pins defined in an array to make loops easier; not something you can do with #define.

It is probably a good practice to use #define instead of a variable for single I/O pins

Or use a "const" declaration.

I was under the impression that const will still treat a variable as a variable, except that the complier will not allow it to be changed. Which means RAM is still consumed on a value that never changes. It would seem that #define is a more efficient method in this case.

AWOL: Or use a "const" declaration.

Not exactly. const does not prevent the thing being declared from taking up space -- it has an presence in RAM whose address can be obtained. It is not the same as literally plugging in the value, or even forcing it to live in PROGMEM. The most precious commodity in Arduino land is RAM, and I would prefer to get out of the habit of wasting it on constants.

Using const declarations has a ton of important advantages -- including type safety, sensible scoping and the ability of the compiler to make sense of what you're doing and give useful error messages when you screw up. All things that CPP macros completely bungle.

I was under the impression that const will still treat a variable as a variable

Yes, impressions are great, but what does actual experience tell you?

const int pin = 12;

void setup ()
  pinMode (pin, OUTPUT);
ldi r24,  0x0C
ldi r22, 0x01
  call 0x114

Did you see any RAM use there?

Contents of section .rodata._ZL3pin:
 0000 0c00                                 ..

Although this would be removed if it wasn't referenced.

static const int pin = 13;

But it starts to look a lot less beginner-friendly, doesn't it? Arduino is aimed significantly toward non-programmers. Introducing complications, even just "#define", is generally avoided. Yes, using an int for an otherwise constant pin number uses a couple extra bytes of ram that aren't really needed, and a couple of extra instructions to access it. So? In the vast majority of sketches, those will be irrelevant.