Passing global variables as const reference - c++

The following code compiles and works. The value displayed of both a and n are 4.
#include <iostream>
using namespace std;
int a = 2;
void foo(int const&n)
{
a = n*2;
cout<<"a = "<<a<<" n = "<<n<<endl;
}
int main()
{
foo(a);
}
OUTPUT: a = 4 n = 4
Why does the compiler not complain about n being a const reference? For example, the following code fails to compile.
#include <iostream>
using namespace std;
int a = 2;
void foo(int const&a)
{
a = a*2;
cout<<"a = "<<a<<endl;
}
int main()
{
foo(a);
}
OUTPUT: In function 'void foo(const int&)':
10:7: error: assignment of read-only reference 'a'
How are the two cases different ?

In the first case you're assigning to a global variable a. n changes because it's a reference to the mutable global variable. Changing a is allowed, but changing n directly is forbidden.
In the second case you're trying to re-assign to the const argument a. This is forbidden as a is const.
What you've done is shadow global variable a with a local variable. In the second example, within foo the global variable named a does not exist, instead there's an argument that occupies that name.

Related

Default argument initializer: Local variable error in clang but not msvc

In Visual Studio 2022 the code below compiles fine with the MSVC compiler selected but gives the indicated error with the clang compiler selected. My understanding is that a local variable is one whose defining declaration is inside a function. Could someone please clarify?
"...default argument references local variable 'bar' of enclosing function"
int bar = 5, x = bar;
int main()
{
extern int bar;
int Test(int foo = bar);
}
found intresting behaviour:
#include <iostream>
using namespace std;
int bar = 5, x = 6;
int Test2(int i = bar)
{
cout << i << endl;
return i;
}
int main()
{
{
int Test2(int foo=x);
Test2(); // prints 6
}
Test2(); // prints 5
}
The output is
6
5
I am using UCRT64 from MSYS to compile.
Using default params, is dangerous. And, somebody may able to override default function param value by redefining function in its scope.

Error after variable used as a function parameter in C?

Can I use a variable as a function parameter after creating the variable while creating the function in C++ or another programming languages?
For example something like below. The code gets error but I wonder if it is possible to do this:
#include <iostream>
using namespace std;
int a = 0;
int dondur(a){
return a;
}
int main(int argc, char **argv)
{
int b=20;
cout << dondur(b);
return 0;
}
Up to the fact, that your function should read
int dondur(int a){
return a;
}
this is legal. The parameter 'int a' hides the global variable. The expected output is therefore 20 and the global variable a=0 remains unchanged.

Variable declaration in C++ within namespaces

In a library I am working with some variables are declared like that:
char &ns::x = y;
However, if I do it that way I get the following error:
error: no member named 'x' in namespace 'ns'
If I rewrite it, it works:
namespace ns {
char &x = y;
}
What exactly is the difference? And why is it working within the library?
If you’re right and the code from the library is exactly as written, then this implies that elsewhere in this library, you’ll find the following declaration:
namespace ns {
extern char& x;
}
In other words, x must have already been declared (and not defined!) inside ns.
The first declaration
char &ns::x = y;
assumes that the name x is already declared in the namespace ns. However this assumption is wrong (in the provided code snippet there is no previous declaration of the variable. Possibly the code snippet is not complete.).
The code snippet can works provided that the variable x is already declared (without its definition) in the namespace ns.
For example
#include <iostream>
namespace ns
{
extern char &x;
}
char y;
char & ns::x = y;
int main() {
return 0;
}
In this code snippet
namespace ns {
char &x = y;
}
there is defined a reference that is initialized by the object y.
The Variable declaration using namespace:
#include <iostream>
using namespace std;
// Variable created inside namespace
namespace first
{
int val = 500;
}
// Global variable
int val = 100;
int main()
{
// Local variable
int val = 200;
// These variables can be accessed from
// outside the namespace using the scope
// operator ::
cout << first::val << '\n';
return 0;
}

If the original variable is missing from the class containing the referenced member, why is it still accessible?

A member of a class is a reference to a local variable. When the local variable is destructed, and the object of this class still exists, you can access the destructed local variable through this object. Why?
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
class c2
{
public:
int& a;
c2(int & c):a(c)
{
}
};
int main()
{
c2 * p;
{
int i = 20;
p = new c2(i);
}
cout << p->a;
system("pause");
return 0;
}
As pointed out by some comments above, the behavior is actually undefined. See in particular the c++ reference on the Lifetime of a temporary:
a temporary bound to a reference in the initializer used in a
new-expression exists until the end of the full expression containing
that new-expression, not as long as the initialized object. If the
initialized object outlives the full expression, its reference member
becomes a dangling reference.
If you use gcc or clang you can compile the program with the option -fsanitize=address: it will crash with
ERROR: AddressSanitizer: stack-use-after-scope
Instead, you will not get any error if you modify your program as follows:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
class c2
{
public:
int& a;
c2(int & c):a(c)
{
}
};
int main()
{
c2 * p;
{
int i = 20;
p = new c2(i);
cout << p->a;
}
delete p;
return 0;
}
(In the program I have inserted a delete p to avoid memory leak)

How do you set a global int inside of a void in C++?

I am making a stat code console app in, C++ visual studio 2013.
I have global intx set as far as I know, and I have some voids made up, the problem is I'm unsure how to set the new global int inside of the void and reuse the int (updated) inside of int main.
please help.
#include < iostream>
using namespace std;
int x = 0;
void change(int x);
void change2(int x);
int main ()
{
change;
system("PAUSE");
change2;
return(0);
}
void change(int x)
{
x = 5;
cout << x << endl;
}
void change2(int x)
{
x = (5 + 1);
cout << x << endl;
}
I think thats a simplified version
Your parameter int x hides the global variable int x, that is why the function doesn't change the global.
You can easily avoid this problem by using different names for each declared variable.
okay, let's look at your code ...
#include <iostream>
using namespace std;
int x = 0; // a global variable.
void change(int x); // declares a function taking an int, returning void
void change2(int x); // declares another function with same signature
int main ()
{
change; // declare a reference to function change()
// no function call: statement has no effect
system("PAUSE");
change2; // declare a reference to function change2()
// no function call: statement has no effect
return(0);
}
void change(int x) // defines a previously declared function
{ // argument x is passed by copy
x = 5; // sets local variable x to 5
cout << x << endl; // global variable x is not affected
}
void change2(int x) // defines another previously declared function
{ // argument x is passed by copy
x = (5 + 1); // sets local variable x to 5+1
cout << x << endl; // global variable x is not affected
}
If you want to change the global variable x, then you must not hide it with a local variable (or explicitly change the global variable):
int x; // global variable
void change_x_to(int i)
{
x=i; // assigns local variable i to global variable x
}
void change2_x_to(int x)
{
::x=x; // assigns local variable x to global variable x
}
int main ()
{
change_x_to(5);
change2_x_to(x+1); // the global x (of course)
assert(x==6);
} // return 0; is automatically created for main()
A scope is a region of the program and broadly speaking there are three places, where variables can be declared:
Inside a function or a block which is called local variables,
Outside of all functions which is called global variables.
You cannot declare a global variable inside a local block although,ye you can use a static global block which can hold the last modified value of your variable.
#include "example.h"
int global_foo = 0;
static int local_foo = 0;
int foo_function()
{
/* sees: global_foo and local_foo
cannot see: local_bar */
return 0;
}
Even his approach is not a good programming practice rather If global variable is to be used across multiple .c files, you should not declare it static. Instead you should declare it extern in header file included by all .c files that need it.
Refer this for further details.