order of declaration matters?

Hello,
I do not understand why in the attached sketch, the order of the line

const int LOGGER_BYTES=4000;//+

relative to the line

const int WATERING_START_ZONE=LOGGER_BYTES;

make a difference for the compiler: if textually above it compiles else it finds errors

could someone please enlighten me on this? Thanks

_17.ino (110 KB)

libraries.zip (11.2 KB)

I guess this does not compile

const int WATERING_START_ZONE=LOGGER_BYTES;
const int LOGGER_BYTES=4000;//+

In C/C++, the compiler needs to know about every variable, function etc before you can use it. So it needs to know about LOGGER_BYTES before it can be used in the WATERING_START_ZONE definition.

The arduino IDE attempts to make that easier for beginners and does a lot of modifications to your original sketch before handing it to the compiler. Sometimes however it drops a stitch.

So understand the C/C++ way, not the Arduino way.

This is normal. Generally speaking you must declare something before you use it. Occasionally this is not possible, for example two functions which call each other, and you must use a forward declarations to get around the problem.

There are some exceptions to this rule in Arduino, I understand. The IDE automatically inserts forward declarations of functions for you so that you can call a function before you have declared it. I seem to remember it does not work for all functions: certain types of parameter or return value can confuse it.

Thank. I would not say it's normal. Wouldn't an extra pass allow to free the programmer from this constraint? Anyway thanks again for this surprising information. I thought I had delusions.

PaulRB:
Generally speaking you must declare something before you use it.

Correct. A data declaration (e.g., extern int myNum, or function prototype) creates an attribute list that describes the data item. However, you cannot actual manipulate that data item until it is defined. A data definition has the same attribute list, but also supplies an lvalue where that item resides in memory. So the use of the keyword extern is essentially saying: "I know this item is not defined in this file, but let me use it here using the following attribute list." (e.g., type = int, ID = myNum, scope = global, etc.) The actual data definition then must appear elsewhere as: int myNum; It then becomes the linker's job to sort out its storage (lvalue).

Wouldn't an extra pass allow to free the programmer from this constraint?

Yes, but that is not how the compiler works, in this case.

The Arduino IDE is somewhat unusual in that preprocessing allows you to skip many, but not all, of the forward declarations that are required by the language syntax.

guy_c:
I would not say it's normal. Wouldn't an extra pass allow to free the programmer from this constraint?

It is precisely as the language specification has defined it to be, and that specification was first created in the mid-1970s. So it's a little ridiculous talk about what you think the language "should" be. It's not going to change, so you better adapt, and learn.
Regards,
Ray L.

econjack:
So the use of the keyword extern is essentially saying: "I know this item is not defined in this file,

It does not mean that.

It means that it is defined somewhere. That somewhere can be in the same file.