Good programming practice?

Hi,

I noticed that some programmers list the used subroutines before Setup as shown in the following pseudo code. Is this good practice or is it unnecessary?

#include <library.h>

int const myPin = 5;

void checkPinIn(void);
time_t getNewTime();
int checkThis (int*);

void setup() {} // put your setup code here, to run once:

void loop() {}  // put your main code here, to run repeatedly:

void checkPinIn() {}

time_t getNewTime() {}

int checkThis(int myPin) {}

Also, some routines are written before Setup and others after Loop. As I understand it, if they are written before Setup it’s because they’re used during the Setup/Start-up of the program. Is it correct?

// constants won't change. Used here to set a pin number :
const int ledPin =  13;      // the number of the LED pin

// Variables will change :
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change :
const long interval = 1000;           // interval at which to blink (milliseconds)

void blinkLed() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

void setup() {pinMode(ledPin, OUTPUT); blinkLed();}

void loop() {}

TIA

That is required by the c/c++ languages but the Arduino build process adds those for you behind the scenes when you do a compile. You can add them if you wish, but it is not necessary when you use the Arduino build process.

Regards,
Ray L.

void checkPinIn(void);
time_t getNewTime();
int checkThis (int*);

These are function prototypes (NOTE - not subroutines) and are needed by the compiler. However, the Arduino IDE automatically creates them for you at compile time, so it is usually not necessary to put them in yourself. This was done to keep it simple for beginners, although the IDE sometimes makes a hash of creating them, which can cause obscure compilation errors so it could be regarded as good practice to put them in the code yourself.

RayLivingston:
That is required by the c/c++ languages but the Arduino build process adds those for you behind the scenes when you do a compile. You can add them if you wish, but it is not necessary when you use the Arduino build process.

Regards,
Ray L.

It can be necessary; I have not managed to create arrays of function pointers before the the functions themselves are declared (or defined, what's in a name :wink: ).

Not necessary if the function has been defined BEFORE it is otherwise referenced.

sterretje:
It can be necessary; I have not managed to create arrays of function pointers before the the functions themselves are declared (or defined, what's in a name :wink: ).

That is because it puts the prototypes immediately before the first function definition. Given the usual order that most people put things in their sketch (includes, globals, functions), that's after the global variables, so the functions won't be in scope when you declare the array.

The easiest fix is to put a dummy function definition after the includes and before the globals. It doesn't need to be elaborate, just something stupid like this:

void dummydummy() {}

Put this before the globals, and the prototypes will go before it instead of whatever your first function would normally be (usually setup()).

Is this good practice or is it unnecessary?

I do not like programmers that do that. The program starts in main() (which, on the Arduino is a hidden function that calls setup() and loop(), so I like to see main() (or setup() and loop()) at the top. I hate having to scroll all over the place looking for the most important functions.

Classes always have the constructors and destructors at the top (unless the code is crap), so that should tell you something about the way other code should be organized.

(This is one the classic arguments in programming, related to “bottom up” vs “top down” programming. I have sympathy for Paul wanting to see main() at the top, but I’ve also seen fine programs that explicitly put main() LAST in a source file.
(It’s also pretty common for the beginning of a program to contain data definitions and a lot of comments, so you may have to search for main() anyway.) Then there’s the philosophy that says each function should be in its own source file (which doesn’t work well with the Arduino IDE…) Modern IDEs and Editors make it a bit irrelevant - you can usually just say “take me to the main() function!” (At this point, you’ll notice that Arduino does NOT qualify as a modern IDE.) (This is actually a bit unfortunate. Programmers USED to pay some attention to laying out their source code in a way that made sense. It might not have been your favorite style, but … still sensible. Now, not so much :frowning: )

At this point, you'll notice that Arduino does NOT qualify as a modern IDE.

More importantly, the forum does not provide a way to search in one thread. The browser search happily jumps to another post in a thread, making it difficult to find text.

PaulS:
I do not like programmers that do that. The program starts in main() (which, on the Arduino is a hidden function that calls setup() and loop(), so I like to see main() (or setup() and loop()) at the top. I hate having to scroll all over the place looking for the most important functions.

Classes always have the constructors and destructors at the top (unless the code is crap), so that should tell you something about the way other code should be organized.

This is amongst the reasons I like placing them at the BOTTOM of the file where they are quick to get to instead of to be searched for between the header includes, global, etc...