Difference between local scope and function scope - c++

Once I assumed that these two have the same meaning but after reading more about it i'm still not clear about the difference. Doesn't the local scope sometimes refer to scope of function?
and what does it mean that only labels have a function scope?

void doSomething()
{ <-------
{ <---- |
| |
int a; Local Scope Function Scope
| |
} <---- |
} <-------
Function Scope is between outer { }.
Local scope is between inner { }
Note that, any scope created by {``} can be called as the local scope while the {``} at the beginning of the function body create the Function scope.
So, Sometimes a Local Scope can be same as Function Scope.
what does it mean that only labels have a function scope?
Labels are nothing but identifiers followed by a colon. Labeled statements are used as targets for goto statements. Labels can be used anywhere in the function in which they appear, but cannot be referenced outside the function body. Hence they are said to have Function Scope.
Code Example:
int doSomething(int x, int y, int z)
{
label: x += (y + z); /* label has function scope*/
if (x > 1)
goto label;
}
int doSomethingMore(int a, int b, int c)
{
if (a > 1)
goto label; /* illegal jump to undefined label */
}

Local scope is the area between an { and it's closing }. Function scope is the area between the opening { of a function and its closing }, which may contain more "local" scopes. A label is visible in the entirety of the function within which it is defined, e.g.
int f( int a )
{
int b = 8;
if ( a > 14 )
{
int c = 50;
label:
return c - a - b;
}
if ( a > 7 ) goto label;
return -99;
}
int c is not visible outside its enclosing block. label is visible outside its enclosing block, but only to function scope.

Doesn't the local scope sometimes refer to scope of function?
Yes. In most C-derived languages, variables are valid in the scope in which they're declared. If you declare a variable inside a function, but not within any other code block, then that variable is usually called a "local" or "automatic" variable. You can refer to it anywhere in the function. On the other hand, if you declare your variable inside another code block -- say, in the body of a conditional statement, then the variable is valid only inside that block. Several other answers here give good examples.
and what does it mean that only labels have a function scope?
Context would be helpful, but it means that you can't jump from one function to a label in a different function.
void foo(int a) {
if (a == 0) goto here; // okay -- 'here' is inside this function
printf("a is not zero\n");
goto there; // not okay -- 'there' is not inside this function
here:
return;
}
void bar(int b) {
if (b == 0) goto there; // okay -- 'there' is in this function
printf("b is not zero\n");
there:
return;
}
Not to stir up a hornet's nest, but the scope of labels probably won't come up too often. Labels are mainly useful with the goto statement, which is needed only very rarely if ever, and even if you did choose to use goto you probably wouldn't even think of trying to jump into a different function.

The scope of the function is slightly larger than the scope of the function body: The function arguments are in the outer scope, while local variables are only in the inner one. This is most visibly manifest in a function-try-block:
void f(int a) try {
// function body
} catch(...) {
// catch block
}
Inside the catch block, only the variables in function scope are still in scope, but not the local variables.
Of course you can and do also introduce further, deeper nested scopes all the time, e.g. in for loop bodies or conditional bodies.

bool m[3][3];
void f1()
{
int i;
// redefining a variable with the same name in the same scope isn't possible
//int i; //error C2086: 'int i' : redefinition
}
void f2()
{
int i; // ok, same name as the i in f1(), different function scope.
{
int i; // ok, same name as the i above, but different local scope.
}
// the scope if the following i is local to the for loop, so it's ok, too.
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (m[i][j])
goto loopExit;
}
}
loopExit:
std::cout << "done checking m";
// redefining a label with the same name in the same function isn't possible
// loopExit:; // error C2045: 'loopExit' : label redefined
}
void f3()
{
loopExit:; // ok, same label name as in f2(), but different function scope
}

Related

How to implement local variables that can be used in other places with the same conditions in C++

How to get the following code to work?
int main(){
bool flag = true;
if(flag){
// note that I donot want to define variable globally.
int a = 5;
}
if(flag){
// but I still want to use this local variable within the same condition.
a++;
}
}
Note that I don't want to define this variable globally or use a static variable.
I'm curious if there is a way for c++ to make local variables available in all regions with the same conditions?
What you ask for literally is a local variable that is not a local variable. Thats not possible.
On the other hand, you basically want data + code, thats a class. If you wrap it in a class your function can look like this:
int main(){
Foo f;
f.doSomething();
}
And the class can be this
struct Foo {
bool flag = false;
int a = 0;
void doSomething() {
if (flag) ++a;
}
};
What you're directly asking for isn't possible. You'll have to declare something up front. If it's about avoiding construction of objects until you have some relevant detail, you could use std::optional
int main()
{
std::optional<int> a;
if(flag)
{
a = 10;
}
if(a)
{
*a++;
}
}
You set the variable's scope to be the scope you want it to be.
int main(){
bool flag = true;
// declare it in this scope if you want it to persist
// thru this scope
int a;
if(flag){
a = 5;
}
if(flag){
a++;
}
}
No.
According to section 6.4.3, basic.scope.block:
1 Each
(1.1) selection or iteration statement ([stmt.select], [stmt.iter]),
[...]
(1.4) compound statement ([stmt.block]) that is not the compound-statement of a handler
introduces a block scope that includes that statement or handler.
A variable that belongs to a block scope is a block variable.
According to section 6.7.5.4, basic.stc.auto, clause 1:
Variables that belong to a block or parameter scope and are not explicitly declared static, thread_­local, or extern have automatic storage duration. The storage for these entities lasts until the block in which they are created exits.

Why didn't the value of x change when the condition is true?

int x = 1;
if (x > 0)
int x = 2;
cout << x;
I expected the output would to be 2 because the condition is true, but what happens here?
I received 1 as output.
You've shadowed the variable.
This occurs when a variable declared within one scope has the same name as a variable declared in an outer scope.
Making this modification will give the output you expect:
int x = 1;
if (x > 0) {
x = 2; // now you're modifying the same x
}
cout << x;
In c++ variable or other symbol declarations are local to their scope, redeclaring them in a different scope is called shadowing, and you will see no effect of the assignment outside of your current scope level. This concerns
Local scope (everything within braces {} or immediately appearing after a control flow statement like if, else, case, while or for)
Typical examples:
int i = 5;
if(i == 5)
int i = 2; // Single statement scope following the if
// Changes the local variable's value
int j = 42;
if(j == 42) {
int j = 2; // Scoped block local variable
// Changes the local variable's value
}
Class scope (any class member variables)
Typical examples:
class MyClass {
int myMember_;
public:
MyClass(int aValue) {
int myMember_; // another local variable in the constructor function
myMember_ = aValue; // Changes the local variable's value
}
};
class MyClass {
int myMember_;
public:
MyClass(int aValue) {
int myMember_ = aValue; // Changes the local variable's value
}
};
Namespace scope (any namespace global variables).
Same principle as above. Namespaces can shadow variables (symbols) from other namespaces
Your c++ compiler should probably give you a warning about the appearance of one of the above mentioned situations.
With specifically GCC (g++) you can force that using the -Wshadow compiler flag.

Do functions have access to variables in the immediate outer scope without parameter input to the function in C++?

Do functions have access to variables in the immediate outerscope without parameter input to the function in C++?
=========
Here is a code I am working on
#include...
void ReadGrid();
void SaveGrid();
int main(){
ReadGrid();
}
void ReadGrid() {
int m=1;
int n[]={1,2,3};
vector<int> o(3,10);
SaveGrid();
}
void SaveGrid() {
int a=m;
int b=n[1];
int c=o[1];
}
Why can't I access the variables in the ReadGrid() functions in SaveGrid(), doesn't the local scope of SaveGrid() treat the scope of ReadGrid() as Global when SaveGrid() is called?
Your question might be better formed thus:
When function a() calls function b(), does b() automatically get visibility into all of a()'s local variables?
And the answer is … no. They are still different block scopes, regardless of your call stack.
Each set of braces denotes a separate scope, so if you create a block with braces, and declare variables inside them, they will not be viisble outside of it. If you create nested blocks of braces, they have inner block has access to the outer block, but not the other way around.
This also applies not only to function (which always have their scope), but also to blocks inside a function as well.
i.e. Two different variables named i, no nameclash because of different scopes:
{
int i;
}
{
int i;
}
Here we have access.
{
int i;
{
int x = i; <== in scope
}
int y = x; <== error
}
If you want to have a set ov variables assoicated to some logical function, then you should put them inside a class or struct.
No, but this is where objects can come into play, e.g. in this pseudo code they share the same data:
class Grid {
private:
int m;
int n[];
vector<int> o;
public:
void ReadGrid(){
// get m,n, and o
}
void SaveGrid() {
// put m,n, and o
}
}
int main(){
Grid grid;
grid.ReadGrid();
}
No what are trying to do is illogical.
If you want the value of m to be available to both ReadGrid and SaveGrid then you must defint "m" as a global variable and you can initialise it in ReadGrid and use the same value in SaveGrid.
Here is a snippet, for your reference
#include...
void ReadGrid();
void SaveGrid();
int m;// global variable
int n[];//global variable
int main(){
ReadGrid();
}
void ReadGrid() {
m=1;
n[]={1,2,3};
SaveGrid();
}
void SaveGrid() {
int a=m;
int b=n[1];
}

Difference between static, auto, global and local variable in the context of c and c++

I’ve a bit confusion about static, auto, global and local variables.
Somewhere I read that a static variable can only be accessed within the function, but they still exist (remain in the memory) after the function returns.
However, I also know that a local variable also does the same, so what is the difference?
There are two separate concepts here:
scope, which determines where a name can be accessed, and
storage duration, which determines when a variable is created and destroyed.
Local variables (pedantically, variables with block scope) are only accessible within the block of code in which they are declared:
void f() {
int i;
i = 1; // OK: in scope
}
void g() {
i = 2; // Error: not in scope
}
Global variables (pedantically, variables with file scope (in C) or namespace scope (in C++)) are accessible at any point after their declaration:
int i;
void f() {
i = 1; // OK: in scope
}
void g() {
i = 2; // OK: still in scope
}
(In C++, the situation is more complicated since namespaces can be closed and reopened, and scopes other than the current one can be accessed, and names can also have class scope. But that's getting very off-topic.)
Automatic variables (pedantically, variables with automatic storage duration) are local variables whose lifetime ends when execution leaves their scope, and are recreated when the scope is reentered.
for (int i = 0; i < 5; ++i) {
int n = 0;
printf("%d ", ++n); // prints 1 1 1 1 1 - the previous value is lost
}
Static variables (pedantically, variables with static storage duration) have a lifetime that lasts until the end of the program. If they are local variables, then their value persists when execution leaves their scope.
for (int i = 0; i < 5; ++i) {
static int n = 0;
printf("%d ", ++n); // prints 1 2 3 4 5 - the value persists
}
Note that the static keyword has various meanings apart from static storage duration. On a global variable or function, it gives it internal linkage so that it's not accessible from other translation units; on a C++ class member, it means there's one instance per class rather than one per object. Also, in C++ the auto keyword no longer means automatic storage duration; it now means automatic type, deduced from the variable's initialiser.
First of all i say that you should google this as it is defined in detail in many places
Local
These variables only exist inside the specific function that creates them. They are unknown to other functions and to the main program. As such, they are normally implemented using a stack. Local variables cease to exist once the function that created them is completed. They are recreated each time a function is executed or called.
Global
These variables can be accessed (ie known) by any function comprising the program. They are implemented by associating memory locations with variable names. They do not get recreated if the function is recalled.
/* Demonstrating Global variables */
#include <stdio.h>
int add_numbers( void ); /* ANSI function prototype */
/* These are global variables and can be accessed by functions from this point on */
int value1, value2, value3;
int add_numbers( void )
{
auto int result;
result = value1 + value2 + value3;
return result;
}
main()
{
auto int result;
value1 = 10;
value2 = 20;
value3 = 30;
result = add_numbers();
printf("The sum of %d + %d + %d is %d\n",
value1, value2, value3, final_result);
}
Sample Program Output
The sum of 10 + 20 + 30 is 60
The scope of global variables can be restricted by carefully placing the declaration. They are visible from the declaration until the end of the current source file.
#include <stdio.h>
void no_access( void ); /* ANSI function prototype */
void all_access( void );
static int n2; /* n2 is known from this point onwards */
void no_access( void )
{
n1 = 10; /* illegal, n1 not yet known */
n2 = 5; /* valid */
}
static int n1; /* n1 is known from this point onwards */
void all_access( void )
{
n1 = 10; /* valid */
n2 = 3; /* valid */
}
Static: Static object is an object that persists from the time it's constructed until the end of the program. So, stack and heap objects are excluded. But global objects, objects at namespace scope, objects declared static inside classes/functions, and objects declared at file scope are included in static objects. Static objects are destroyed when the program stops running.I suggest you to see this tutorial list
AUTO:C, C++
(Called automatic variables.)
All variables declared within a block of code are automatic by default, but this can be made explicit with the auto keyword.[note 1] An uninitialized automatic variable has an undefined value until it is assigned a valid value of its type.[1]
Using the storage class register instead of auto is a hint to the compiler to cache the variable in a processor register. Other than not allowing the referencing operator (&) to be used on the variable or any of its subcomponents, the compiler is free to ignore the hint.
In C++, the constructor of automatic variables is called when the execution reaches the place of declaration. The destructor is called when it reaches the end of the given program block (program blocks are surrounded by curly brackets). This feature is often used to manage resource allocation and deallocation, like opening and then automatically closing files or freeing up memory.SEE WIKIPEDIA
Difference is static variables are those variables: which allows a value to be retained from one call of the function to another.
But in case of local variables the scope is till the block/ function lifetime.
For Example:
#include <stdio.h>
void func() {
static int x = 0; // x is initialized only once across three calls of func()
printf("%d\n", x); // outputs the value of x
x = x + 1;
}
int main(int argc, char * const argv[]) {
func(); // prints 0
func(); // prints 1
func(); // prints 2
return 0;
}
Local variables are non existent in the memory after the function termination.
However static variables remain allocated in the memory throughout the life of the program irrespective of whatever function.
Additionally from your question, static variables can be declared locally in class or function scope and globally in namespace or file scope. They are allocated the memory from beginning to end, it's just the initialization which happens sooner or later.
static is a heavily overloaded word in C and C++. static variables in the context of a function are variables that hold their values between calls. They exist for the duration of the program.
local variables persist only for the lifetime of a function or whatever their enclosing scope is. For example:
void foo()
{
int i, j, k;
//initialize, do stuff
} //i, j, k fall out of scope, no longer exist
Sometimes this scoping is used on purpose with { } blocks:
{
int i, j, k;
//...
} //i, j, k now out of scope
global variables exist for the duration of the program.
auto is now different in C and C++. auto in C was a (superfluous) way of specifying a local variable. In C++11, auto is now used to automatically derive the type of a value/expression.
When a variable is declared static inside a class then it becomes a shared variable for all objects of that class which means that the variable is longer specific to any object.
For example: -
#include<iostream.h>
#include<conio.h>
class test
{
void fun()
{
static int a=0;
a++;
cout<<"Value of a = "<<a<<"\n";
}
};
void main()
{
clrscr();
test obj1;
test obj2;
test obj3;
obj1.fun();
obj2.fun();
obj3.fun();
getch();
}
This program will generate the following output: -
Value of a = 1
Value of a = 2
Value of a = 3
The same goes for globally declared static variable. The above code will generate the same output if we declare the variable a outside function void fun()
Whereas if u remove the keyword static and declare a as a non-static local/global variable then the output will be as follows: -
Value of a = 1
Value of a = 1
Value of a = 1

Scope within a scope, do or don't?

Although the example below compiles fine except for the last line with the error, I'd like to know the ins and outs of this 'scoping' within a scope? Also the terminology of this, if any.
Consider these brackets:
void func()
{
int i = 0;
{ // nice comment to describe this scope
while( i < 10 )
++i;
}
{ // nice comment to describe this scope
int j= 0;
while( j< 10 )
++j;
}
i = 0; // OK
// j = 0; // error C2065
}
consider this:
error C2065: 'j' : undeclared identifier
edit:
Accepted answer is from bitmask, although I think everyone should place it in the context of anio's answer. Especially, quote: "perhaps you should break your function into 2 functions"
Do. By all means!
Keeping data as local as possible and as const as possible has two main advantages:
side effects are reduced and the code becomes more functional
with complex objects, destructors can be be invoked early within a function, as soon as the data is not needed any more
Additionally, this can be useful for documentation to summarise the job a particular part of a function does.
I've heard this being referred to as explicit or dummy scoping.
I personally don't find much value in adding additional scoping within a function. If you are relying on it to separate parts of your function, perhaps you should break your function into 2 functions. Smaller functions are better than larger ones. You should strive to have small easily understood functions.
The one legitimate use of scopes within a function is for limiting the duration of a lock:
int doX()
{
// Do some work
{
//Acquire lock
} // Lock automatically released because of RAII
}
The inner scope effectively limits the code over which the lock is held. I believe this is common practice.
Yes, definitely - it's a great habit to always keep your variables as local as possible! Some examples:
for (std::string line; std::getline(std::cin, line); ) // does not
{ // leak "line"
// process "line" // into ambient
} // scope
int result;
{ // putting this in a separate scope
int a = foo(); // allows us to copy/paste the entire
a += 3; // block without worrying about
int b = bar(a); // repeated declarators
result *= (a + 2*b);
}
{ // ...and we never really needed
int a = foo(); // a and b outside of this anyway!
a += 3;
int b = bar(a);
result *= (a + 2*b);
}
Sometimes a scope is necessary for synchronisation, and you want to keep the critical section as short as possible:
int global_counter = 0;
std::mutex gctr_mx;
void I_run_many_times_concurrently()
{
int a = expensive_computation();
{
std::lock_guard<std::mutex> _(gctr_mx);
global_counter += a;
}
expensive_cleanup();
}
The explicit scoping is usually not done for commenting purposes, but I don't see any harm in doing it if you feel it makes your code more readable.
Typical usage is for avoiding name clashes and controlling when the destructors are called.
A pair of curly braces defines a scope. Names declared or defined within a scope are not visible outside that scope, which is why j is not defined at the end. If a name in a scope is the same as a name defined earlier and outside that scope, it hides the outer name.