Global or local

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












2














I'm new to Arduino and embedded, but understand that it is often better to use global instead of local variables (such as here or here).



I have this simple code (from here):



//Libraries
#include <DHT.h>;

//Constants
#define DHTPIN 2 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino


//Variables
float hum; //Stores humidity value
float temp; //Stores temperature value

void setup()

Serial.begin(9600);
dht.begin();



void loop()

//Read data and store it to variables hum and temp
hum = dht.readHumidity();
temp= dht.readTemperature();
//Print temp and humidity values to serial monitor
Serial.print("Humidity: ");
Serial.print(hum);
Serial.print(" %, Temp: ");
Serial.print(temp);
Serial.println(" Celsius");
delay(2000); //Delay 2 sec.



My ancient C programmer training (Unix servers) says I must move variables hum and temp to loop(), or is it better on Arduino to leave them as globals?










share|improve this question





















  • This depends on how you define "better". For instance, when is "global" necessary? When can a "local" work just as well?
    – Mikael Patel
    Dec 20 '18 at 9:24






  • 4




    Since the AVR CPU is a register-rich system, putting the variables in loop may well cause the compiler to go "Oh, I have enough registers to store this information. I don't need these variables in memory since they get thrown away straight after using them. I'll delete them and just use internal registers instead.". Optimizations are great :)
    – Majenko
    Dec 20 '18 at 10:02







  • 1




    If you are an ancient C programmer, then try functions with parameters "by reference". The compiler can do more optimizations with that. Passing a global variable by reference is almost the same for the compiler as using the global variable in the function, but with the parameter by reference it still does look good because the used variables are nicely declared as parameters. By the way, the dht22 is not accurate, try something better.
    – Jot
    Dec 20 '18 at 10:57











  • @Jot - it's cheap! And my project is not critical. Or is there something better in the same price bracket?
    – minisaurus
    Dec 20 '18 at 13:45






  • 1




    The humidity that the dht22 returns is not accurate, it is only an indication and can be used to check if the humidity goes up or down. When it measures 60%, the relative humidity can be between 40% and 80%. The good sensors with i2c are still 2% or 3% inaccurate. Those sensors are for example the bme280, bme680, htu21d, sht31-d, si7021. Those sensors are 3.3v and the arduino uno is 5. You might need level shifters for the i2c bus. For just the temperature, the ds18b20 is the best choice, good and cheap.
    – Jot
    Dec 20 '18 at 16:03















2














I'm new to Arduino and embedded, but understand that it is often better to use global instead of local variables (such as here or here).



I have this simple code (from here):



//Libraries
#include <DHT.h>;

//Constants
#define DHTPIN 2 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino


//Variables
float hum; //Stores humidity value
float temp; //Stores temperature value

void setup()

Serial.begin(9600);
dht.begin();



void loop()

//Read data and store it to variables hum and temp
hum = dht.readHumidity();
temp= dht.readTemperature();
//Print temp and humidity values to serial monitor
Serial.print("Humidity: ");
Serial.print(hum);
Serial.print(" %, Temp: ");
Serial.print(temp);
Serial.println(" Celsius");
delay(2000); //Delay 2 sec.



My ancient C programmer training (Unix servers) says I must move variables hum and temp to loop(), or is it better on Arduino to leave them as globals?










share|improve this question





















  • This depends on how you define "better". For instance, when is "global" necessary? When can a "local" work just as well?
    – Mikael Patel
    Dec 20 '18 at 9:24






  • 4




    Since the AVR CPU is a register-rich system, putting the variables in loop may well cause the compiler to go "Oh, I have enough registers to store this information. I don't need these variables in memory since they get thrown away straight after using them. I'll delete them and just use internal registers instead.". Optimizations are great :)
    – Majenko
    Dec 20 '18 at 10:02







  • 1




    If you are an ancient C programmer, then try functions with parameters "by reference". The compiler can do more optimizations with that. Passing a global variable by reference is almost the same for the compiler as using the global variable in the function, but with the parameter by reference it still does look good because the used variables are nicely declared as parameters. By the way, the dht22 is not accurate, try something better.
    – Jot
    Dec 20 '18 at 10:57











  • @Jot - it's cheap! And my project is not critical. Or is there something better in the same price bracket?
    – minisaurus
    Dec 20 '18 at 13:45






  • 1




    The humidity that the dht22 returns is not accurate, it is only an indication and can be used to check if the humidity goes up or down. When it measures 60%, the relative humidity can be between 40% and 80%. The good sensors with i2c are still 2% or 3% inaccurate. Those sensors are for example the bme280, bme680, htu21d, sht31-d, si7021. Those sensors are 3.3v and the arduino uno is 5. You might need level shifters for the i2c bus. For just the temperature, the ds18b20 is the best choice, good and cheap.
    – Jot
    Dec 20 '18 at 16:03













2












2








2







I'm new to Arduino and embedded, but understand that it is often better to use global instead of local variables (such as here or here).



I have this simple code (from here):



//Libraries
#include <DHT.h>;

//Constants
#define DHTPIN 2 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino


//Variables
float hum; //Stores humidity value
float temp; //Stores temperature value

void setup()

Serial.begin(9600);
dht.begin();



void loop()

//Read data and store it to variables hum and temp
hum = dht.readHumidity();
temp= dht.readTemperature();
//Print temp and humidity values to serial monitor
Serial.print("Humidity: ");
Serial.print(hum);
Serial.print(" %, Temp: ");
Serial.print(temp);
Serial.println(" Celsius");
delay(2000); //Delay 2 sec.



My ancient C programmer training (Unix servers) says I must move variables hum and temp to loop(), or is it better on Arduino to leave them as globals?










share|improve this question













I'm new to Arduino and embedded, but understand that it is often better to use global instead of local variables (such as here or here).



I have this simple code (from here):



//Libraries
#include <DHT.h>;

//Constants
#define DHTPIN 2 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino


//Variables
float hum; //Stores humidity value
float temp; //Stores temperature value

void setup()

Serial.begin(9600);
dht.begin();



void loop()

//Read data and store it to variables hum and temp
hum = dht.readHumidity();
temp= dht.readTemperature();
//Print temp and humidity values to serial monitor
Serial.print("Humidity: ");
Serial.print(hum);
Serial.print(" %, Temp: ");
Serial.print(temp);
Serial.println(" Celsius");
delay(2000); //Delay 2 sec.



My ancient C programmer training (Unix servers) says I must move variables hum and temp to loop(), or is it better on Arduino to leave them as globals?







arduino-uno variables






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Dec 20 '18 at 9:12









minisaurus

1133




1133











  • This depends on how you define "better". For instance, when is "global" necessary? When can a "local" work just as well?
    – Mikael Patel
    Dec 20 '18 at 9:24






  • 4




    Since the AVR CPU is a register-rich system, putting the variables in loop may well cause the compiler to go "Oh, I have enough registers to store this information. I don't need these variables in memory since they get thrown away straight after using them. I'll delete them and just use internal registers instead.". Optimizations are great :)
    – Majenko
    Dec 20 '18 at 10:02







  • 1




    If you are an ancient C programmer, then try functions with parameters "by reference". The compiler can do more optimizations with that. Passing a global variable by reference is almost the same for the compiler as using the global variable in the function, but with the parameter by reference it still does look good because the used variables are nicely declared as parameters. By the way, the dht22 is not accurate, try something better.
    – Jot
    Dec 20 '18 at 10:57











  • @Jot - it's cheap! And my project is not critical. Or is there something better in the same price bracket?
    – minisaurus
    Dec 20 '18 at 13:45






  • 1




    The humidity that the dht22 returns is not accurate, it is only an indication and can be used to check if the humidity goes up or down. When it measures 60%, the relative humidity can be between 40% and 80%. The good sensors with i2c are still 2% or 3% inaccurate. Those sensors are for example the bme280, bme680, htu21d, sht31-d, si7021. Those sensors are 3.3v and the arduino uno is 5. You might need level shifters for the i2c bus. For just the temperature, the ds18b20 is the best choice, good and cheap.
    – Jot
    Dec 20 '18 at 16:03
















  • This depends on how you define "better". For instance, when is "global" necessary? When can a "local" work just as well?
    – Mikael Patel
    Dec 20 '18 at 9:24






  • 4




    Since the AVR CPU is a register-rich system, putting the variables in loop may well cause the compiler to go "Oh, I have enough registers to store this information. I don't need these variables in memory since they get thrown away straight after using them. I'll delete them and just use internal registers instead.". Optimizations are great :)
    – Majenko
    Dec 20 '18 at 10:02







  • 1




    If you are an ancient C programmer, then try functions with parameters "by reference". The compiler can do more optimizations with that. Passing a global variable by reference is almost the same for the compiler as using the global variable in the function, but with the parameter by reference it still does look good because the used variables are nicely declared as parameters. By the way, the dht22 is not accurate, try something better.
    – Jot
    Dec 20 '18 at 10:57











  • @Jot - it's cheap! And my project is not critical. Or is there something better in the same price bracket?
    – minisaurus
    Dec 20 '18 at 13:45






  • 1




    The humidity that the dht22 returns is not accurate, it is only an indication and can be used to check if the humidity goes up or down. When it measures 60%, the relative humidity can be between 40% and 80%. The good sensors with i2c are still 2% or 3% inaccurate. Those sensors are for example the bme280, bme680, htu21d, sht31-d, si7021. Those sensors are 3.3v and the arduino uno is 5. You might need level shifters for the i2c bus. For just the temperature, the ds18b20 is the best choice, good and cheap.
    – Jot
    Dec 20 '18 at 16:03















This depends on how you define "better". For instance, when is "global" necessary? When can a "local" work just as well?
– Mikael Patel
Dec 20 '18 at 9:24




This depends on how you define "better". For instance, when is "global" necessary? When can a "local" work just as well?
– Mikael Patel
Dec 20 '18 at 9:24




4




4




Since the AVR CPU is a register-rich system, putting the variables in loop may well cause the compiler to go "Oh, I have enough registers to store this information. I don't need these variables in memory since they get thrown away straight after using them. I'll delete them and just use internal registers instead.". Optimizations are great :)
– Majenko
Dec 20 '18 at 10:02





Since the AVR CPU is a register-rich system, putting the variables in loop may well cause the compiler to go "Oh, I have enough registers to store this information. I don't need these variables in memory since they get thrown away straight after using them. I'll delete them and just use internal registers instead.". Optimizations are great :)
– Majenko
Dec 20 '18 at 10:02





1




1




If you are an ancient C programmer, then try functions with parameters "by reference". The compiler can do more optimizations with that. Passing a global variable by reference is almost the same for the compiler as using the global variable in the function, but with the parameter by reference it still does look good because the used variables are nicely declared as parameters. By the way, the dht22 is not accurate, try something better.
– Jot
Dec 20 '18 at 10:57





If you are an ancient C programmer, then try functions with parameters "by reference". The compiler can do more optimizations with that. Passing a global variable by reference is almost the same for the compiler as using the global variable in the function, but with the parameter by reference it still does look good because the used variables are nicely declared as parameters. By the way, the dht22 is not accurate, try something better.
– Jot
Dec 20 '18 at 10:57













@Jot - it's cheap! And my project is not critical. Or is there something better in the same price bracket?
– minisaurus
Dec 20 '18 at 13:45




@Jot - it's cheap! And my project is not critical. Or is there something better in the same price bracket?
– minisaurus
Dec 20 '18 at 13:45




1




1




The humidity that the dht22 returns is not accurate, it is only an indication and can be used to check if the humidity goes up or down. When it measures 60%, the relative humidity can be between 40% and 80%. The good sensors with i2c are still 2% or 3% inaccurate. Those sensors are for example the bme280, bme680, htu21d, sht31-d, si7021. Those sensors are 3.3v and the arduino uno is 5. You might need level shifters for the i2c bus. For just the temperature, the ds18b20 is the best choice, good and cheap.
– Jot
Dec 20 '18 at 16:03




The humidity that the dht22 returns is not accurate, it is only an indication and can be used to check if the humidity goes up or down. When it measures 60%, the relative humidity can be between 40% and 80%. The good sensors with i2c are still 2% or 3% inaccurate. Those sensors are for example the bme280, bme680, htu21d, sht31-d, si7021. Those sensors are 3.3v and the arduino uno is 5. You might need level shifters for the i2c bus. For just the temperature, the ds18b20 is the best choice, good and cheap.
– Jot
Dec 20 '18 at 16:03










3 Answers
3






active

oldest

votes


















8














No. If you have the choice, locals are usually better, because they
minimize the risk of name collision, and they help make the program
clearer by keeping the variable definition close to the place where it
is used. In your example, hum and temp should be locals, as there is
no good reason to make them globals.



However, sometimes you don't have the choice. If a variable is used in
both setup() and loop(), then it needs to be global. This is the
case of dht in your example.



Sometimes a variable is used in many functions. Even if you can make it
local, by passing it around through function parameters, doing so
doesn't make the program more readable. In that case you may also prefer
to keep it global.



Sometimes a variable that is used in only one function needs to be
statically allocated in order to preserve its value across calls to the
function. In this case the variable could be a static local. However,
since the static keyword is somewhat obscure for beginner programmers,
Arduino tutorials tend to use globals whenever static storage is needed.
You are not required to follow this practice, although you may want to
if you are writing for an audience of novices.



In any case, the take away of your first two links is not that you
should prefer globals: it's that sometimes there is a good reason for
making a variable global, and that's fine.






share|improve this answer




















  • Thanks for all your answers, I've changed the code, and it's good to know I don't need to change my practices too much :) (Global variables were banned in all the development environments I worked in in the 1990s) So am I right to conclude that I only NEED to use a global if I refer to it in setup() and loop()? Everything else can be local and passed around?
    – minisaurus
    Dec 20 '18 at 10:21






  • 1




    @minisaurus: Yes, that's right. However, now that he ban is lifted, I suggest you try to avoid thinking of globals as evil. If you find yourself passing a variable around through many functions, consider making it global: does that hurt the program's readability? If the answer is “no”, then a global is probably a good choice.
    – Edgar Bonet
    Dec 20 '18 at 10:32










  • I'm out of touch, but is the ban really lifted in professional environments with several developers, APIs, libraries and who knows how many files of source code? But I can see how globals maybe aren't a big problem in these single file small Arduino projects.
    – minisaurus
    Dec 20 '18 at 13:50






  • 1




    @minisaurus: I don't know on these environments. My answer is specifically for the kind of programs you write on smallish embedded devices.
    – Edgar Bonet
    Dec 20 '18 at 15:36


















2














The general rule of good practice is to minimize the scope of a variable to necessary minimum. Write the code to be readable and maintainable, don't do premature optimization.



The variables hum and temp should be defined only in loop(). The compiler can optimize it by putting them to global space or using MCU registers only, to avoid repeated creation on stack.






share|improve this answer






























    0














    Not an answer, but I thought some of you may be interested in the C coding standards of some projects in the 1990s (based on the EDS standards, if I remember correctly).



    A summary of the rules is:



    • No goto

    • No global variables

    • All functions (including main) to return an integer which is either SUCCESS or FAILURE

    • All variables declared at start of function

    • All variables declared on a separate line

    • No "in-line" initialising of variables

    • All variables initialised, usually to zero, including mallocs

    • No in-line if's

    • Probably more things that I can't remember

    An example program:



    #include <stdio.h>
    #include <stdlib.h>

    #define SUCCESS 0
    #define FAILURE !SUCCESS

    int log_error(char *msg)
    int rv;

    rv = SUCCESS;

    fprintf(stderr, "%sn", msg);

    return(rv);


    int function2(void)
    int rv;

    rv = SUCCESS;

    return(rv);


    int function1(void)
    int rv;
    int i;
    char *mem;

    rv = FAILURE;
    i = 0;
    mem = 0;

    if(NULL == (mem = malloc(400)))
    log_error("Malloc error");
    else
    for(i=0; i<400; i++)
    mem[i] = 0;

    if(SUCCESS != (rv = function2()))
    log_error("function2");
    else
    rv = SUCCESS;
    free(mem);


    return(rv);


    int main(int argc, char **argv)
    int rv;

    rv = FAILURE;

    if(SUCCESS != (rv = function1()))
    log_error("function1 error");


    return(rv);



    Bit different to the way K&R wrote UNIX, and perhaps not too relevant to embedded? I'm not sure which I prefer, I guess both styles have their place depending on the makeup of a team :)






    share|improve this answer




















    • You very wisely pointed out that not all of these rules are universal. Just to provide an illustration, the Linux kernel coding style contradicts several of the above, including the bans on gotos (sec. 7) and global variables (sec. 4), having to always return a status code (sec. 16), and variable initialization within the declaration (example on sec. 7).
      – Edgar Bonet
      Dec 23 '18 at 20:28










    Your Answer






    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("schematics", function ()
    StackExchange.schematics.init();
    );
    , "cicuitlab");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "540"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f59900%2fglobal-or-local%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    8














    No. If you have the choice, locals are usually better, because they
    minimize the risk of name collision, and they help make the program
    clearer by keeping the variable definition close to the place where it
    is used. In your example, hum and temp should be locals, as there is
    no good reason to make them globals.



    However, sometimes you don't have the choice. If a variable is used in
    both setup() and loop(), then it needs to be global. This is the
    case of dht in your example.



    Sometimes a variable is used in many functions. Even if you can make it
    local, by passing it around through function parameters, doing so
    doesn't make the program more readable. In that case you may also prefer
    to keep it global.



    Sometimes a variable that is used in only one function needs to be
    statically allocated in order to preserve its value across calls to the
    function. In this case the variable could be a static local. However,
    since the static keyword is somewhat obscure for beginner programmers,
    Arduino tutorials tend to use globals whenever static storage is needed.
    You are not required to follow this practice, although you may want to
    if you are writing for an audience of novices.



    In any case, the take away of your first two links is not that you
    should prefer globals: it's that sometimes there is a good reason for
    making a variable global, and that's fine.






    share|improve this answer




















    • Thanks for all your answers, I've changed the code, and it's good to know I don't need to change my practices too much :) (Global variables were banned in all the development environments I worked in in the 1990s) So am I right to conclude that I only NEED to use a global if I refer to it in setup() and loop()? Everything else can be local and passed around?
      – minisaurus
      Dec 20 '18 at 10:21






    • 1




      @minisaurus: Yes, that's right. However, now that he ban is lifted, I suggest you try to avoid thinking of globals as evil. If you find yourself passing a variable around through many functions, consider making it global: does that hurt the program's readability? If the answer is “no”, then a global is probably a good choice.
      – Edgar Bonet
      Dec 20 '18 at 10:32










    • I'm out of touch, but is the ban really lifted in professional environments with several developers, APIs, libraries and who knows how many files of source code? But I can see how globals maybe aren't a big problem in these single file small Arduino projects.
      – minisaurus
      Dec 20 '18 at 13:50






    • 1




      @minisaurus: I don't know on these environments. My answer is specifically for the kind of programs you write on smallish embedded devices.
      – Edgar Bonet
      Dec 20 '18 at 15:36















    8














    No. If you have the choice, locals are usually better, because they
    minimize the risk of name collision, and they help make the program
    clearer by keeping the variable definition close to the place where it
    is used. In your example, hum and temp should be locals, as there is
    no good reason to make them globals.



    However, sometimes you don't have the choice. If a variable is used in
    both setup() and loop(), then it needs to be global. This is the
    case of dht in your example.



    Sometimes a variable is used in many functions. Even if you can make it
    local, by passing it around through function parameters, doing so
    doesn't make the program more readable. In that case you may also prefer
    to keep it global.



    Sometimes a variable that is used in only one function needs to be
    statically allocated in order to preserve its value across calls to the
    function. In this case the variable could be a static local. However,
    since the static keyword is somewhat obscure for beginner programmers,
    Arduino tutorials tend to use globals whenever static storage is needed.
    You are not required to follow this practice, although you may want to
    if you are writing for an audience of novices.



    In any case, the take away of your first two links is not that you
    should prefer globals: it's that sometimes there is a good reason for
    making a variable global, and that's fine.






    share|improve this answer




















    • Thanks for all your answers, I've changed the code, and it's good to know I don't need to change my practices too much :) (Global variables were banned in all the development environments I worked in in the 1990s) So am I right to conclude that I only NEED to use a global if I refer to it in setup() and loop()? Everything else can be local and passed around?
      – minisaurus
      Dec 20 '18 at 10:21






    • 1




      @minisaurus: Yes, that's right. However, now that he ban is lifted, I suggest you try to avoid thinking of globals as evil. If you find yourself passing a variable around through many functions, consider making it global: does that hurt the program's readability? If the answer is “no”, then a global is probably a good choice.
      – Edgar Bonet
      Dec 20 '18 at 10:32










    • I'm out of touch, but is the ban really lifted in professional environments with several developers, APIs, libraries and who knows how many files of source code? But I can see how globals maybe aren't a big problem in these single file small Arduino projects.
      – minisaurus
      Dec 20 '18 at 13:50






    • 1




      @minisaurus: I don't know on these environments. My answer is specifically for the kind of programs you write on smallish embedded devices.
      – Edgar Bonet
      Dec 20 '18 at 15:36













    8












    8








    8






    No. If you have the choice, locals are usually better, because they
    minimize the risk of name collision, and they help make the program
    clearer by keeping the variable definition close to the place where it
    is used. In your example, hum and temp should be locals, as there is
    no good reason to make them globals.



    However, sometimes you don't have the choice. If a variable is used in
    both setup() and loop(), then it needs to be global. This is the
    case of dht in your example.



    Sometimes a variable is used in many functions. Even if you can make it
    local, by passing it around through function parameters, doing so
    doesn't make the program more readable. In that case you may also prefer
    to keep it global.



    Sometimes a variable that is used in only one function needs to be
    statically allocated in order to preserve its value across calls to the
    function. In this case the variable could be a static local. However,
    since the static keyword is somewhat obscure for beginner programmers,
    Arduino tutorials tend to use globals whenever static storage is needed.
    You are not required to follow this practice, although you may want to
    if you are writing for an audience of novices.



    In any case, the take away of your first two links is not that you
    should prefer globals: it's that sometimes there is a good reason for
    making a variable global, and that's fine.






    share|improve this answer












    No. If you have the choice, locals are usually better, because they
    minimize the risk of name collision, and they help make the program
    clearer by keeping the variable definition close to the place where it
    is used. In your example, hum and temp should be locals, as there is
    no good reason to make them globals.



    However, sometimes you don't have the choice. If a variable is used in
    both setup() and loop(), then it needs to be global. This is the
    case of dht in your example.



    Sometimes a variable is used in many functions. Even if you can make it
    local, by passing it around through function parameters, doing so
    doesn't make the program more readable. In that case you may also prefer
    to keep it global.



    Sometimes a variable that is used in only one function needs to be
    statically allocated in order to preserve its value across calls to the
    function. In this case the variable could be a static local. However,
    since the static keyword is somewhat obscure for beginner programmers,
    Arduino tutorials tend to use globals whenever static storage is needed.
    You are not required to follow this practice, although you may want to
    if you are writing for an audience of novices.



    In any case, the take away of your first two links is not that you
    should prefer globals: it's that sometimes there is a good reason for
    making a variable global, and that's fine.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Dec 20 '18 at 9:56









    Edgar Bonet

    24k22344




    24k22344











    • Thanks for all your answers, I've changed the code, and it's good to know I don't need to change my practices too much :) (Global variables were banned in all the development environments I worked in in the 1990s) So am I right to conclude that I only NEED to use a global if I refer to it in setup() and loop()? Everything else can be local and passed around?
      – minisaurus
      Dec 20 '18 at 10:21






    • 1




      @minisaurus: Yes, that's right. However, now that he ban is lifted, I suggest you try to avoid thinking of globals as evil. If you find yourself passing a variable around through many functions, consider making it global: does that hurt the program's readability? If the answer is “no”, then a global is probably a good choice.
      – Edgar Bonet
      Dec 20 '18 at 10:32










    • I'm out of touch, but is the ban really lifted in professional environments with several developers, APIs, libraries and who knows how many files of source code? But I can see how globals maybe aren't a big problem in these single file small Arduino projects.
      – minisaurus
      Dec 20 '18 at 13:50






    • 1




      @minisaurus: I don't know on these environments. My answer is specifically for the kind of programs you write on smallish embedded devices.
      – Edgar Bonet
      Dec 20 '18 at 15:36
















    • Thanks for all your answers, I've changed the code, and it's good to know I don't need to change my practices too much :) (Global variables were banned in all the development environments I worked in in the 1990s) So am I right to conclude that I only NEED to use a global if I refer to it in setup() and loop()? Everything else can be local and passed around?
      – minisaurus
      Dec 20 '18 at 10:21






    • 1




      @minisaurus: Yes, that's right. However, now that he ban is lifted, I suggest you try to avoid thinking of globals as evil. If you find yourself passing a variable around through many functions, consider making it global: does that hurt the program's readability? If the answer is “no”, then a global is probably a good choice.
      – Edgar Bonet
      Dec 20 '18 at 10:32










    • I'm out of touch, but is the ban really lifted in professional environments with several developers, APIs, libraries and who knows how many files of source code? But I can see how globals maybe aren't a big problem in these single file small Arduino projects.
      – minisaurus
      Dec 20 '18 at 13:50






    • 1




      @minisaurus: I don't know on these environments. My answer is specifically for the kind of programs you write on smallish embedded devices.
      – Edgar Bonet
      Dec 20 '18 at 15:36















    Thanks for all your answers, I've changed the code, and it's good to know I don't need to change my practices too much :) (Global variables were banned in all the development environments I worked in in the 1990s) So am I right to conclude that I only NEED to use a global if I refer to it in setup() and loop()? Everything else can be local and passed around?
    – minisaurus
    Dec 20 '18 at 10:21




    Thanks for all your answers, I've changed the code, and it's good to know I don't need to change my practices too much :) (Global variables were banned in all the development environments I worked in in the 1990s) So am I right to conclude that I only NEED to use a global if I refer to it in setup() and loop()? Everything else can be local and passed around?
    – minisaurus
    Dec 20 '18 at 10:21




    1




    1




    @minisaurus: Yes, that's right. However, now that he ban is lifted, I suggest you try to avoid thinking of globals as evil. If you find yourself passing a variable around through many functions, consider making it global: does that hurt the program's readability? If the answer is “no”, then a global is probably a good choice.
    – Edgar Bonet
    Dec 20 '18 at 10:32




    @minisaurus: Yes, that's right. However, now that he ban is lifted, I suggest you try to avoid thinking of globals as evil. If you find yourself passing a variable around through many functions, consider making it global: does that hurt the program's readability? If the answer is “no”, then a global is probably a good choice.
    – Edgar Bonet
    Dec 20 '18 at 10:32












    I'm out of touch, but is the ban really lifted in professional environments with several developers, APIs, libraries and who knows how many files of source code? But I can see how globals maybe aren't a big problem in these single file small Arduino projects.
    – minisaurus
    Dec 20 '18 at 13:50




    I'm out of touch, but is the ban really lifted in professional environments with several developers, APIs, libraries and who knows how many files of source code? But I can see how globals maybe aren't a big problem in these single file small Arduino projects.
    – minisaurus
    Dec 20 '18 at 13:50




    1




    1




    @minisaurus: I don't know on these environments. My answer is specifically for the kind of programs you write on smallish embedded devices.
    – Edgar Bonet
    Dec 20 '18 at 15:36




    @minisaurus: I don't know on these environments. My answer is specifically for the kind of programs you write on smallish embedded devices.
    – Edgar Bonet
    Dec 20 '18 at 15:36











    2














    The general rule of good practice is to minimize the scope of a variable to necessary minimum. Write the code to be readable and maintainable, don't do premature optimization.



    The variables hum and temp should be defined only in loop(). The compiler can optimize it by putting them to global space or using MCU registers only, to avoid repeated creation on stack.






    share|improve this answer



























      2














      The general rule of good practice is to minimize the scope of a variable to necessary minimum. Write the code to be readable and maintainable, don't do premature optimization.



      The variables hum and temp should be defined only in loop(). The compiler can optimize it by putting them to global space or using MCU registers only, to avoid repeated creation on stack.






      share|improve this answer

























        2












        2








        2






        The general rule of good practice is to minimize the scope of a variable to necessary minimum. Write the code to be readable and maintainable, don't do premature optimization.



        The variables hum and temp should be defined only in loop(). The compiler can optimize it by putting them to global space or using MCU registers only, to avoid repeated creation on stack.






        share|improve this answer














        The general rule of good practice is to minimize the scope of a variable to necessary minimum. Write the code to be readable and maintainable, don't do premature optimization.



        The variables hum and temp should be defined only in loop(). The compiler can optimize it by putting them to global space or using MCU registers only, to avoid repeated creation on stack.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 20 '18 at 10:54

























        answered Dec 20 '18 at 9:37









        Juraj

        6,6582925




        6,6582925





















            0














            Not an answer, but I thought some of you may be interested in the C coding standards of some projects in the 1990s (based on the EDS standards, if I remember correctly).



            A summary of the rules is:



            • No goto

            • No global variables

            • All functions (including main) to return an integer which is either SUCCESS or FAILURE

            • All variables declared at start of function

            • All variables declared on a separate line

            • No "in-line" initialising of variables

            • All variables initialised, usually to zero, including mallocs

            • No in-line if's

            • Probably more things that I can't remember

            An example program:



            #include <stdio.h>
            #include <stdlib.h>

            #define SUCCESS 0
            #define FAILURE !SUCCESS

            int log_error(char *msg)
            int rv;

            rv = SUCCESS;

            fprintf(stderr, "%sn", msg);

            return(rv);


            int function2(void)
            int rv;

            rv = SUCCESS;

            return(rv);


            int function1(void)
            int rv;
            int i;
            char *mem;

            rv = FAILURE;
            i = 0;
            mem = 0;

            if(NULL == (mem = malloc(400)))
            log_error("Malloc error");
            else
            for(i=0; i<400; i++)
            mem[i] = 0;

            if(SUCCESS != (rv = function2()))
            log_error("function2");
            else
            rv = SUCCESS;
            free(mem);


            return(rv);


            int main(int argc, char **argv)
            int rv;

            rv = FAILURE;

            if(SUCCESS != (rv = function1()))
            log_error("function1 error");


            return(rv);



            Bit different to the way K&R wrote UNIX, and perhaps not too relevant to embedded? I'm not sure which I prefer, I guess both styles have their place depending on the makeup of a team :)






            share|improve this answer




















            • You very wisely pointed out that not all of these rules are universal. Just to provide an illustration, the Linux kernel coding style contradicts several of the above, including the bans on gotos (sec. 7) and global variables (sec. 4), having to always return a status code (sec. 16), and variable initialization within the declaration (example on sec. 7).
              – Edgar Bonet
              Dec 23 '18 at 20:28















            0














            Not an answer, but I thought some of you may be interested in the C coding standards of some projects in the 1990s (based on the EDS standards, if I remember correctly).



            A summary of the rules is:



            • No goto

            • No global variables

            • All functions (including main) to return an integer which is either SUCCESS or FAILURE

            • All variables declared at start of function

            • All variables declared on a separate line

            • No "in-line" initialising of variables

            • All variables initialised, usually to zero, including mallocs

            • No in-line if's

            • Probably more things that I can't remember

            An example program:



            #include <stdio.h>
            #include <stdlib.h>

            #define SUCCESS 0
            #define FAILURE !SUCCESS

            int log_error(char *msg)
            int rv;

            rv = SUCCESS;

            fprintf(stderr, "%sn", msg);

            return(rv);


            int function2(void)
            int rv;

            rv = SUCCESS;

            return(rv);


            int function1(void)
            int rv;
            int i;
            char *mem;

            rv = FAILURE;
            i = 0;
            mem = 0;

            if(NULL == (mem = malloc(400)))
            log_error("Malloc error");
            else
            for(i=0; i<400; i++)
            mem[i] = 0;

            if(SUCCESS != (rv = function2()))
            log_error("function2");
            else
            rv = SUCCESS;
            free(mem);


            return(rv);


            int main(int argc, char **argv)
            int rv;

            rv = FAILURE;

            if(SUCCESS != (rv = function1()))
            log_error("function1 error");


            return(rv);



            Bit different to the way K&R wrote UNIX, and perhaps not too relevant to embedded? I'm not sure which I prefer, I guess both styles have their place depending on the makeup of a team :)






            share|improve this answer




















            • You very wisely pointed out that not all of these rules are universal. Just to provide an illustration, the Linux kernel coding style contradicts several of the above, including the bans on gotos (sec. 7) and global variables (sec. 4), having to always return a status code (sec. 16), and variable initialization within the declaration (example on sec. 7).
              – Edgar Bonet
              Dec 23 '18 at 20:28













            0












            0








            0






            Not an answer, but I thought some of you may be interested in the C coding standards of some projects in the 1990s (based on the EDS standards, if I remember correctly).



            A summary of the rules is:



            • No goto

            • No global variables

            • All functions (including main) to return an integer which is either SUCCESS or FAILURE

            • All variables declared at start of function

            • All variables declared on a separate line

            • No "in-line" initialising of variables

            • All variables initialised, usually to zero, including mallocs

            • No in-line if's

            • Probably more things that I can't remember

            An example program:



            #include <stdio.h>
            #include <stdlib.h>

            #define SUCCESS 0
            #define FAILURE !SUCCESS

            int log_error(char *msg)
            int rv;

            rv = SUCCESS;

            fprintf(stderr, "%sn", msg);

            return(rv);


            int function2(void)
            int rv;

            rv = SUCCESS;

            return(rv);


            int function1(void)
            int rv;
            int i;
            char *mem;

            rv = FAILURE;
            i = 0;
            mem = 0;

            if(NULL == (mem = malloc(400)))
            log_error("Malloc error");
            else
            for(i=0; i<400; i++)
            mem[i] = 0;

            if(SUCCESS != (rv = function2()))
            log_error("function2");
            else
            rv = SUCCESS;
            free(mem);


            return(rv);


            int main(int argc, char **argv)
            int rv;

            rv = FAILURE;

            if(SUCCESS != (rv = function1()))
            log_error("function1 error");


            return(rv);



            Bit different to the way K&R wrote UNIX, and perhaps not too relevant to embedded? I'm not sure which I prefer, I guess both styles have their place depending on the makeup of a team :)






            share|improve this answer












            Not an answer, but I thought some of you may be interested in the C coding standards of some projects in the 1990s (based on the EDS standards, if I remember correctly).



            A summary of the rules is:



            • No goto

            • No global variables

            • All functions (including main) to return an integer which is either SUCCESS or FAILURE

            • All variables declared at start of function

            • All variables declared on a separate line

            • No "in-line" initialising of variables

            • All variables initialised, usually to zero, including mallocs

            • No in-line if's

            • Probably more things that I can't remember

            An example program:



            #include <stdio.h>
            #include <stdlib.h>

            #define SUCCESS 0
            #define FAILURE !SUCCESS

            int log_error(char *msg)
            int rv;

            rv = SUCCESS;

            fprintf(stderr, "%sn", msg);

            return(rv);


            int function2(void)
            int rv;

            rv = SUCCESS;

            return(rv);


            int function1(void)
            int rv;
            int i;
            char *mem;

            rv = FAILURE;
            i = 0;
            mem = 0;

            if(NULL == (mem = malloc(400)))
            log_error("Malloc error");
            else
            for(i=0; i<400; i++)
            mem[i] = 0;

            if(SUCCESS != (rv = function2()))
            log_error("function2");
            else
            rv = SUCCESS;
            free(mem);


            return(rv);


            int main(int argc, char **argv)
            int rv;

            rv = FAILURE;

            if(SUCCESS != (rv = function1()))
            log_error("function1 error");


            return(rv);



            Bit different to the way K&R wrote UNIX, and perhaps not too relevant to embedded? I'm not sure which I prefer, I guess both styles have their place depending on the makeup of a team :)







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Dec 23 '18 at 17:33









            minisaurus

            1133




            1133











            • You very wisely pointed out that not all of these rules are universal. Just to provide an illustration, the Linux kernel coding style contradicts several of the above, including the bans on gotos (sec. 7) and global variables (sec. 4), having to always return a status code (sec. 16), and variable initialization within the declaration (example on sec. 7).
              – Edgar Bonet
              Dec 23 '18 at 20:28
















            • You very wisely pointed out that not all of these rules are universal. Just to provide an illustration, the Linux kernel coding style contradicts several of the above, including the bans on gotos (sec. 7) and global variables (sec. 4), having to always return a status code (sec. 16), and variable initialization within the declaration (example on sec. 7).
              – Edgar Bonet
              Dec 23 '18 at 20:28















            You very wisely pointed out that not all of these rules are universal. Just to provide an illustration, the Linux kernel coding style contradicts several of the above, including the bans on gotos (sec. 7) and global variables (sec. 4), having to always return a status code (sec. 16), and variable initialization within the declaration (example on sec. 7).
            – Edgar Bonet
            Dec 23 '18 at 20:28




            You very wisely pointed out that not all of these rules are universal. Just to provide an illustration, the Linux kernel coding style contradicts several of the above, including the bans on gotos (sec. 7) and global variables (sec. 4), having to always return a status code (sec. 16), and variable initialization within the declaration (example on sec. 7).
            – Edgar Bonet
            Dec 23 '18 at 20:28

















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Arduino Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f59900%2fglobal-or-local%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown






            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay