Out of context, it's hard to be sure, but, yes, I think so.
Global variables are the exception, I suppose. They are not inside any { } block.
EDIT: Another exception would be function parameters. They are just outside a { } block but their scope is limited to inside that block. Actually, there may be no { } block at all, for example
Most if not all of these types of questions would be contained in the C++ standard, which you have to pay to buy official versions, but you can find "drafts" or unofficial versions all over the internet. The following repository maintains a "live" draft. https://github.com/timsong-cpp/cppwp
section 6 of the above document explains scope in general. 6.4.3 explains block scope.
6.4.3 Block scope[basic.scope.block]
1 A name declared in a block ([stmt.block]) is local to that block; it has block scope. Its potential scope begins at its point of declaration ([basic.scope.pdecl]) and ends at the end of its block. A variable declared at block scope is a local variable.
2 The name declared in an exception-declaration is local to the handler and shall not be redeclared in the outermost block of the handler.
3 Names declared in the init-statement, the for-range-declaration, and in the condition of if, while, for, and switch statements are local to the if, while, for, or switch statement (including the controlled statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for the if statement, any of the outermost blocks) of the controlled statement.
[Example 1:
if (int x = f()) {
int x; // error: redeclaration of x
}
else {
int x; // error: redeclaration of x
}
— end example]
It literally means what it said: scope is confined within braces. So, yeah, for loops, if, etc. can all have variables defined that are only scoped for their duration. But this also works:
int a = 5;
Serial.begin(115200);
Serial.println(a);
{
int a = 10;
Serial.println(a);
}
Serial.println(a);
Basically correct. The scope of a variable declaration is, generally, the rest of the enclosing block.
It sort of acts like each statement is in a block since the arguments to the for (A; B; C) share a scope with the body. Similarly, the argument list of a function declaration shares a scope with the body of the function.
Note: 'if', 'while', 'switch' are more properly called 'statements', not 'functions'.
I confess... I use a TON of global variables when Arduino programming. Probably MOST of my variables are global. The exception would be for-loops or other situations where the variable isn't needed in any other scope.
It just doesn't seem worth the trouble of using pointers & references with these small self-contained programs.
The scope of a declared variable is confined within braces ({}). Because of declaration, the a within braces ({}) is different from that of a outside {}. If I remove the data type from a (that is within {}), then all a's are the same.
int a = 5;
Serial.begin(115200);
Serial.println(a);
{
a = 10;
Serial.println(a);
}
Serial.println(a);
And a step further...sometimes you want to limit the scope of a variable but NOT it's lifetime! For example, if you declare a variable within a code block, example int foo; , then the variable is "destroyed" when you exit the block, i.e. it lifetime has ended. However, if you declare that same variable with the static keyword, example static int foo;, then it is not visible outside of that block, however it retains it's value when you reenter that block.
void setup()
{
Serial.begin(9600);
callProg();
//Serial.println(x); out of scope
callProg();
}
void loop()
{
}
void callProg()
{
static byte x = 5;
x++;
Serial.println(x);
}
Output:
6
7
Because of static keyword, the variable is initialized only once. After that the variable is assigned new values as needed.
The scope of the variable x is limited within the user-defined function -- callProg(). Scope refers to that region of the "whole program" where the variable is recognized and processed.
Lifetime refers to the "duration of time" for which the value of the variable remains available within the scoped region. In the above sketch, the lifetime of x is equal to the lifetime of the sketch.
Global variables should be used where needed only.
It can be very confusing if a global variable is changed unintentionally.
You do not need pointers or references to pass parameters to a function.
The use of functions with parameter will help you structure your code, make it reusable and make it readable for others (incl. yourself).
Programmers often use CAPITALS for global variables to prevent unintentional reuse and shading in local scopes.
Because Processing was in Java, and Wiring was based on Processing, and Arduino was a fork of Wiring, it is common in sketches to use Java styling for variables.
Thank you all. I picked one post as a solution (because it was the earliest) however many of the responses are helpful.
As a casual user, I find the "official documents" are written by wannabe lawyers. I was getting an error that acted like a variable scope issue. It was frustrating for me to search many C++ references looking for a clear (to me) rule to understand scope. I knew the Setup, Loop and functions (subroutines) limited scope but I had not considered if, for and while. I finally found a statement stating referring to braces.... then BINGO.
I hope this thread helps others in the same state of mind as I was.
As for global's, I try to minimize them only because I feel it's the "right" way to code as opposed to the easy way. Perhaps in a Pro Mini It doesn't really matter...still.
A long time ago I was told a good way to specify global' s was to precede the name with a lower case "g"
I find that following good coding practices pays off, even in tiny programs. It's not as important of course, but it still helps you avoid shooting yourself in the foot.
I wrote a small piece of code (fifty lines?) a few weeks back and hacked it together from several unrelated existing programs I already had and didn't bother to clean it up properly. That, combined with the fact that I can never get the syntax for cron right on the first go led to about six unnecessary bugs that took as many days to eliminate. Should have done it right in the first place.
To each their own, but once you start down that road, it's just a hop, skip and a jump to Hungarian notation and weird incomprehensible variable names. No thanks!
Not really related but years ago I had an engineer working for me (not a programmer by schooling). It was a complex program for testing a product we were building. The computer and I/O interface was a HP (long before PC's). Anyway he used nearly sentences for the variables.
I think I will try the all Upper case for globals. I see your point that the prefix can be more difficult to identify globals.