Is there any way to access a local variable in outer scope in C++?
You can declare a new reference as an alias like so
int main (void)
{
int v = 2; // local
int &vlocal = v;
{
int v = 3; // within subscope
cout << "local: " << vlocal << endl;
}
}
But I would avoid this practice this altogether. I have spent hours debugging such a construct because a variable was displayed in debugger as changed because of scope and I couldn't figure out how it got changed.
How can I use local variable in another scope in C++?
There is no way to accomplish that. The language does not provide a way to differentiate between the first var
in main
from the second var
.
If you ever write production code, please refrain from using such variables. It will lead to buggy code. You will be confused about which variable is in scope in a given line of code.
Accessing variables with the same name at different scopes
No you can't, a (2) is hidden.
Ref: 3.3.7/1
A name can be hidden by an explicit
declaration of that same name in a
nested declarative region or derived
class (10.2).
Ref: 3.4.3/1
The name of a class or namespace
member can be referred to after the ::
scope resolution operator (5.1)
applied to a nested-name-specifier
that nominates its class or namespace.
During the lookup for a name preceding
the :: scope resolution operator,
object, function, and enumerator names
are ignored. If the name found is not
a class-name (clause 9) or
namespace-name (7.3.1), the program is
ill-formed.
What does local variables at the outermost scope of the function may not use the same name as any parameter mean?
The outermost scope of the function is the block that defines the function's body. You can put other (inner) blocks inside that, and declare variables in those which are local to that block. Variables in inner blocks can have the same name as those in an outer block, or the function parameters; they hide the names in the outer scope. Variables in the outer block can't have the same name as a function parameter.
To demonstrate:
void f(int a) // function has a parameter
{ // beginning of function scope
int b; // OK: local variable
{ // beginning of inner block
int a; // OK: hides parameter
int b; // OK: hides outer variable
} // end of inner block
int a; // Error: can't have same name as parameter
}
Accessing variables in an enclosing scope(not global) hidden by local declaration in C++?
This is unfortunately not possible. Compiler warning options, like -Wshadow
for GCC, can help avoiding such situations:
-Wshadow
Warn whenever a local variable or type declaration shadows another variable, parameter, type, class member (in C++), or instance
variable (in Objective-C) or whenever a built-in function is shadowed.
Note that in C++, the compiler warns if a local variable shadows an
explicit typedef, but not if it shadows a struct/class/enum. Same as
-Wshadow=global.
In your example, for instance, you'd get a warning like:
: In function '
int main()
'::7:9: error: declaration of '
i
' shadows a previous local
[-Werror=shadow]7 | int i = 5;
|
As @L. F. points out in a comment below, you can use references to still have access to the other i
:
#include <iostream>
int main() {
int i = 10;
if (1) {
int& nonlocal_i = i; // just before shadowing
int i = 5;
std::cout << "Local i: " << i << std::endl;
std::cout << "Main's i: " << nonlocal_i << std::endl;
}
return 0;
}
But -Wshadow
will still complain, and if you were going the extra mile to find an alternative name, you could just name the local i
differently.
Note:
As user4581301 points out in a comment, code like int& i = i;
doesn't do what you'd expect in an inner scope:
#include <iostream>
int main()
{
int i = 4;
{
int& i = i;
std::cout << i;
}
}
It tries to use the variable i
to initialize itself. In Microsoft's compiler you get a compilation error like:
error C4700: uninitialized local variable 'i' used
In GCC, if you turn all the warnings on, you get this message:
error: reference 'i' is initialized with itself [-Werror=init-self]
But it silently compiles and does the wrong thing if you don't have the warnings turned on
C++, Accessing a non-global variable declared inside other method
This is undefined behavior: once the function finishes, accessing a variable inside it by pointer or reference makes the program invalid, and may cause a crash.
It is perfectly valid, however, to access a variable when you go "back" on the stack:
void assign(int* ptr) {
*ptr = 1234;
}
int main() {
int kek = 5;
cout << kek << endl;
assign(&kek);
cout << kek << endl;
}
Note how assign
has accessed the value of a local variable declared inside another function. This is legal, because main
has not finished at the time the access has happened.
Is it well defined to access a variable from an outer scope before it is redefined?
Is this well defined or it just happened to work?
It is well-defined. The scope of a variable declared inside a {...}
block starts at the point of declaration and ends at the closing brace. From this C++17 Draft Standard:
6.3.3 Block scope [basic.scope.block]
1 A name declared in a block (9.3) is local to that
block; it has block scope. Its potential scope begins at its point of
declaration (6.3.2) and ends at the end of its block. A variable
declared at block scope is a local variable.
This code compiles with no warnings in gcc-11
That surprises me. The clang-cl compiler (in Visual Studio 2019, 'borrowing' the /Wall
switch from MSVC) gives this:
warning : declaration shadows a local variable [-Wshadow]
Using both -Wall
and -Wpedantic
in GCC 11.2 doesn't generate this warning; however, explicitly adding -Wshadow
does give it. Not sure what "general" -Wxxx
switch GCC needs to make it appear.
Accessing shadowed variables from inner scope
You cannot just simply achieve this as the inner variable just overshadows your outer scope variable.
If an inner block declares a variable with the same name as the variable declared by the outer block, then the visibility of the outer block variable ends at the point of the declaration by inner block.
However, if you still need to achieve this, you can do something to store the variable values in a stack that saves the variable values per scope. This is something similar to what is done during function calls (just a revised version to store only variable you require).
I would still suggest you to instead use a separate name for variables as this reduces readability of code.
Related Topics
Tackling Class Imbalance: Scaling Contribution to Loss and Sgd
Why Is Protected Constructor Raising an Error This This Code
Parsing Strings of User Input Using the Cparse Library from Git
Which Boost Features Overlap with C++11
Floating Point Comparison Revisited
C++, How to Determine If a Windows Process Is Running
Accessing a Protected Member of a Base Class in Another Subclass
Why Does Same_As Concept Check Type Equality Twice
Stl Remove Doesn't Work as Expected
How to Detect Existence of a Class Using Sfinae
Declaring Multiple Object Pointers on One Line Causes Compiler Error
How to Cout a Float Number with N Decimal Places
Explain Morris Inorder Tree Traversal Without Using Stacks or Recursion
C++11 Lambda Implementation and Memory Model
In What Ways Do C++ Exceptions Slow Down Code When There Are No Exceptions Thown