Notifications
Clear all

Where should a function definition be placed?

8 Posts
6 Users
5 Likes
151 Views
barrie
(@barrie)
Trusted Member
Joined: 3 months ago
Posts: 86
Topic starter  

Is there a specific location where a function should be defined?

Anywhere except loop and setup?

Before the function is called (I think I saw one after the function was called)?

 


   
Quote
Ron
 Ron
(@zander)
Famed Member
Joined: 2 years ago
Posts: 3403
 

In the global section before loop and setup.

"Don't tell people how to do things. Tell them what to do and let them surprise you with their results.” - G.S. Patton, Gen. USA
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon


   
ReplyQuote
robotBuilder
(@robotbuilder)
Noble Member
Joined: 3 years ago
Posts: 1554
 

@zander 

It seems with the Arduino IDE the "global space" is anywhere outside the loop and setup both of which might be themselves functions compiled into a c++ template program?  Your reply I presume meant where you believe functions should be placed rather than where they can be placed.

void setup(){
  Serial.begin(9600);
}

void loop() {
  int i = 2;
  int j = 3;
  int k;

  k = myMultiplyFunction(i, j); // k now contains 6
  Serial.println(k);
  delay(500);
}

int myMultiplyFunction(int x, int y){
  int result;
  result = x * y;
  return result;
}

 

 

void setup(){
  Serial.begin(9600);
}

int myMultiplyFunction(int x, int y){
  int result;
  result = x * y;
  return result;
}

void loop() {
  int i = 2;
  int j = 3;
  int k;

  k = myMultiplyFunction(i, j); // k now contains 6
  Serial.println(k);
  delay(500);
}


 

 

This post was modified 3 months ago by robotBuilder

   
ReplyQuote
Inq
 Inq
(@inq)
Noble Member
Joined: 8 months ago
Posts: 959
 
Posted by: @barrie

Is there a specific location where a function should be defined?

Anywhere except loop and setup?

Before the function is called (I think I saw one after the function was called)?

 

There is no standard for that.  It often falls to personal preference... OR even more often, the compiler requires a preference. 

For instance, I prefer to have the setup() and loop() at the top as @robotbuilder suggests.  I find it annoying to have to sift through potentially thousands of lines of code to find them.  However, I have found on a couple of instances where the compiler will complain, saying basically, it can't find the function.  Me pointing at the screen to show the compiler, "It's right the $#!+ there!" seems to do no good. 😆 I have never spent the time to determine what it was I did to cause the compiler to lose it's marbles, but when this happens, you have three choices...

(1) Do as @zander suggests and put it at the top.

(2) Declare the function at the top, but leave the definition below the setup/loop.  Using @robotbuilder's sample, I've added a declaration at the top.  This will always satisfy a wayward compiler.

int myMultiplyFunction(int x, int y);   // function decleration

void setup(){
  Serial.begin(9600);
}

void loop() {
  int i = 2;
  int j = 3;
  int k;

  k = myMultiplyFunction(i, j); // k now contains 6
  Serial.println(k);
  delay(500);
}

int myMultiplyFunction(int x, int y){
  int result;
  result = x * y;
  return result;
}

(3) Make it a library.  As your projects grow and especially if you think you'll want to use the same code again in another project, you'll want to make a library out of it.  At first this seems like a lot of trouble, but once you get your "library" bullet-proof, you should never have to look in it again and it'll be a simple concept of adding the header file and just use it!  At first you can add these files to your sketch's folder holding the ino and they will automatically be visible in the Arduino IDE.  Later you'd learn to put them in a "libraries" folder so they are visible to all sketches.  (beyond the scope of this post)    Using @robotbuilder's sample again, you'd make two new files in addition to your sketch file.

Sketch.ino - Note the addition of the include line at the top... just like you'd do when incorporating someone else's libraries.

#include "myLibrary.h"

void setup(){
  Serial.begin(9600);
}

void loop() {
  int i = 2;
  int j = 3;
  int k;

  k = myMultiplyFunction(i, j); // k now contains 6
  Serial.println(k);
  delay(500);
}

myLibrary.h - Contains the declarations, just like using option 2 above.

int myMultiplyFunction(int x, int y);

myLibrary.c - Contains the definitions of your functions.

int myMultiplyFunction(int x, int y){
  int result;
  result = x * y;
  return result;
}

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, Access Point Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
Ron reacted
ReplyQuote
Ron
 Ron
(@zander)
Famed Member
Joined: 2 years ago
Posts: 3403
 

@inq YES, let's have our cake and eat it too!

Sketch.ino - Note the addition of the include line at the top... just like you'd do when incorporating someone else's libraries.

#include "myLibrary.h"

void setup(){
  Serial.begin(9600);
}

void loop() {
  int i = 2;
  int j = 3;
  int k;

  k = myMultiplyFunction(i, j); // k now contains 6
  Serial.println(k);
  delay(500);
}

myLibrary.h - Contains the declarations, just like using option 2 above.

int myMultiplyFunction(int x, int y);

myLibrary.c - Contains the definitions of your functions.

int myMultiplyFunction(int x, int y){
  int result;
  result = x * y;
  return result;
}

"Don't tell people how to do things. Tell them what to do and let them surprise you with their results.” - G.S. Patton, Gen. USA
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon


   
Inq reacted
ReplyQuote
frogandtoad
(@frogandtoad)
Noble Member
Joined: 3 years ago
Posts: 1476
 

@zander

Posted by: @zander

In the global section before loop and setup.

Yes and no! 😉

All C and C++ programs are read top down sequentially, so... what happens if funcA() wants to call funcB() which follows it?  How does funcA() know about funcB()?

I say yes and no, because the Arduino IDE does some trickery, where it virtually places everything in the global namespace, but this is not always the case.

The best thing to do is if you want to define your functions below the setup or loop function, is to provide what is known as a forward declaration of the function signature only, for example:

void area(int, int); // <-- forward declaration

void setup() {
  Serial.begin(9600);
 }

void loop() {
  area(10, 10);

  delay(1000);
 }

/********************************* FUNCTION DEFINITIONS *********************************/
int area(int l, int w) {
  return l * w;
 }

The function declaration above is known as a: "forward declaration".

It alerts the compiler to the fact that there is a function with this name and parameter signature, living somewhere within our program code, so find it and link it into our program compilation.

Note: - The parameter name(s) are not mandatory as per the full definition of the function shown, thus only the type(s) of the parameters the function accepts; are sufficient for use in a forward declaration.

This is why when we have complex programs and libraries, the "extern" keyword comes into play!

Cheers


   
Ron reacted
ReplyQuote
Will
 Will
(@will)
Noble Member
Joined: 1 year ago
Posts: 2112
 

@frogandtoad 

 

That would work even better if you defined it as 

int area(int,int);

instead of void to match the function you're describing.

I was kidnapped by mimes.
They did unspeakable things to me.


   
frogandtoad and Ron reacted
ReplyQuote
frogandtoad
(@frogandtoad)
Noble Member
Joined: 3 years ago
Posts: 1476
 

@will

Posted by: @will

@frogandtoad 

 

That would work even better if you defined it as 

int area(int,int);

instead of void to match the function you're describing.

Dang!

Thanks for picking that up - I originally had it set as 'void' which didn't really make sense, and forgot to change it in the forward declaration.

Just for completeness, here is the corrected version:

int area(int, int); // <-- forward declaration

void setup() {
  Serial.begin(9600);
 }

void loop() {
  Serial.println("Area: " + String(area(10, 10)));

  delay(1000);
 }

/********************************* FUNCTION DEFINITIONS *********************************/
int area(int l, int w) {
  return l * w;
 }

 Cheers


   
ReplyQuote