Why isn't the output 101 while I assigned the previous x to the new x?
int x = 101;
{
int x = x;
std::cout << x << std::endl;
}
Output (garbage):
422634
I thought the second x would be initialized to 101 but it isn't initialized.
Note: The solution in this case is int x = ::x but the question is why it happens.
Point of declaration
The point of declaration for a name is immediately after its complete
declarator and before its initializer... [C++ Standard § 3.3.2/1]
Compiler completes the declaration when it knows enough about declarator.
Above code is equal to the below one:
int x = 101;
{
int x;
x = x; <------------------// Self assignment, assigns an indeterminate value.
std::cout << x << std::endl;
}
Because, the declaration of inner x completed before = (assignment)
int x = x; <--// Now, we have the new `x` which hides the older one,
^ // so it assigns itself to itself
|
+---// Point of declaration,
// here compiler knows everything to declare `x`.
// then declares it.
On the other hand, when we declaring complex objects, the point of declaration is farther. So, the behavior is different.
For example, below code is OK
const int i = 2;
{
int i[i];
^
|
+----// Point of declaration
// compiler has to reach to "]"
// therefore before declaring `i` as an array
// there is just one `i`, the `i` of `const int i=2`
}
In above code, compiler has to know the actual size of the array to complete the declaration, so the point of declaration is ]. Therefore the i within [i] is the outer i because declaration of the i of int i[... isn't completed yet. Thus, it declares an array with 2 elements (int i[2];).
Also, this example shows the point of declaration for an enumerator
const int x = 12;
{
enum { x = x };
^
|
+---// Point of declaration
// compiler has to reach to "}" then
// there is just one `x`, the `x` of `const int x=12`
}
The enumerator x is initialized with the value of the constant x, namely 12.
There's another way to do it.
#include <iostream>
int x = 101;
int main()
{
int x = ::x;
std::cout << x << std::endl;
std::cin.get();
}
variable scope
In front of x will be overwritten.
int x = x;
This one there are two processes.
One: int x;(define variable x and allocate memory and specify the initial value : x = 0);
this moment , the front x will be hidden.
Two: x = x;(Do not find the value x);
Related
#include <iostream>
using namespace std;
int division(int c, int d);
int x = 2;
int y = 2;
int division(int c, int d)
{
return (c/d);
}
int main()
{
cout << "Hello World!\n";
int x = division(x,y);
cout << x;
return 0;
}
I expected the code to show 1 after Hello World!, but it prints 0.
I removed int from in front of x (in main()) and ran it again and it returned 1.
But I also passed x,x to the division function with the int in front of x (in main()) and it returned 1.
So I am not sure how the assignment statement is working.
This expression:
int x = division(x,y);
is equivalent to writing this:
// 'x' was defined globally somewhere here before
int x;
x = division(x, y);
This shadows the previous x variable defined globally and defines a local variable x which again is uninitialized so after passing it in the division() function, your code has Undefined Behavior. (When that happens, the output can be anything, it can be 0, it can even be 1 or something else entirely.)
What you want to do is to remove the declaration and turn it into an assignment instead:
x = division(x,y);
Then the above works properly and gives 1.
You should compile your code at least with -Wall flag.
You would then see a helpful warning message:
foo.cpp: In function ‘int main()’:
foo.cpp:17:21: warning: ‘x’ is used uninitialized [-Wuninitialized]
17 | int x = division(x,y);
| ~~~~~~~~^~~~~
It means that to the division() isn't passed global x, but the local one from main().
It's undefinied behaviour, no different than int z = division(z,y);
After removing int from before x in main() you no longer declare local variable, thus there is only one x in your program (the global one) and from initialization the line turns into plain assignment.
the output of the code is 30.But I am not sure how it is getting to it.
#include <iostream>
int &fun()
{
static int x = 10;
return x;
}
int main()
{
fun() = 30;
std::cout << fun();
return 0;
}
I am expecting that the output will be 10 but its showing 30. how?
Your fun gives a location of an int (since it returns a reference). That location is the static variable x which is initialized (once, conceptually before the program runs) to 10.
Then fun() = 30; is assigning that location. So x gets assigned to 30.
At last cout << fun() displays the content of that location.
If x was some automatic variable your code would have undefined behavior.
PS. A crude way of thinking about & unary reference like int &r = x; is that it sort-of "transforms" your code as: introduce a phantom pointer int *p = &x; (where p is some fresh variable not appearing elsewhere) and replace r with *p, so &r with p, everywhere in the scope of that r.
In the following code, 2 is printed.
int x = 1;
int f(int y)
{
return x;
}
int main() {
x = 2;
printf("%d", f(0));
}
How is it happening if we have static scoping in C? Why isn't 1 printed?
Printing 2 in this case isn't a dynamic scoping, is it?
I thought that in static scoping it should take the nearest x to the function definition.
It does take the nearest x, but since you only have one x it doesn't really matter.
If you change the code to
int x = 1;
int f(int y)
{
return x ;
}
int main() {
int x=2;
printf("%d", f(0));
}
so you have 2 x, the global one and the local one in main you will see 1 getting printed.
Those are usually called dynamic and lexical scoping.
Lexical scoping is determined entirely at compile time, dynamic scoping at runtime.
You only have one variable named "x", so scope is irrelevant to your program.
Here's a program that would be different depending on the scoping rules:
int x = 0;
int f()
{
return x;
}
int main()
{
int x = 1;
printf("%d\n", f(x));
}
Under lexical scoping, f returns the value of the x that is lexically "nearest" - the global one.
So it would print 0;
Under dynamic scoping, f would return the value of the newest x, which is the one in main.
So it would print 1.
The scoping is moot here since you have not declared an x locally that would have otherwise shadowed the global x.
2 is printed.
x is assigned in main to 2 immediately before f is called with the parameter 0.
(Conceptually int x = 1; is ran before main is entered.)
It is the way the compiler generates the assembly/machine code.
first global variable X is stored in memory location "abc"
next main is executed: global variable X at "abc" is changed to 2
Now function f() is called:
function f returns the value of global variable X at "abc": being 2
the return value of f() is printed.
So if you wanted a different X in the main-function scope, you should have made a new object, like in the answer by nwp.
I understood that int x{}; is a kind of default-initialization, but is it exactly the same as writing int x = 0; ?
The result is same in this case.
int x{}; is a kind of default-initialization
Not exactly. See default initialization.
int x{}; is value initialization (since C++11),
This is the initialization performed when a variable is constructed with an empty initializer.
And the effects of value initialization in this case (i.e. neither class type nor array type) are:
4) otherwise, the object is zero-initialized.
Finally the effects of zero initialization in this case are:
If T is a scalar type, the object's initial value is the integral
constant zero explicitly converted to T.
On the other hand, int x = 0; is copy initialization; x is initialized with the value 0.
As #PaulR mentioned, there's a difference that int x{}; is only supported from c++11, while int x = 0 has not such restriction.
In this case they are identical. int x{} will initialise x in the same way as static int x would; i.e. to zero. That said, I find int x = 0 clearer and it has the benefit that it works with older C++ standards.
There is difference:
int x=1.888; will work with x as 1. Lot of trouble later.All professional guys have sometime faced , in their or others' code.
but
int x{1.888}; will NOT compile and save trouble.
They are both the exact same thing. They will both be initialized to 0.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int y{};
int x = 0;
cout << "y: " << y << endl;
cout << "x: " << x << endl;
return 0;
}
OUTPUT:
y: 0
x: 0
Hi I am switching to C++ from C. While reading http://www.gotw.ca/publications/xc++.htm I see this code block.
const int i = 1;
const int j = 2;
struct x
{
int x;
};
namespace y
{
int i[i];
int j = j;
x x;
int y::y = x.x;
};
And I am totally confused about this specially in namespace y section.
Please explain me the behavior of this code and use of namespace. Also I read somewhere that bad use of namespace leading to violating fundamentals of inheritance. Please give me some examples of using namespace brilliantly.
This example is using some horribly obfuscated code to illustrate a point about the scope of names. From C++11 §3.3.6 [basic.scope.namespace] p1:
... A namespace member name has namespace scope. Its potential scope includes its namespace from the name’s point of declaration (3.3.2) onwards ...
point of declaration is defined in §3.3.2 [basic.scope.pdecl] p1:
The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below.
So it is possible to use e.g. the name i from an outer scope in the initializer of something named i in an inner scope. The code in question:
const int i = 1;
const int j = 2;
struct x
{
int x;
};
namespace y
{
int i[i];
int j = j;
x x;
int y::y = x.x;
}
declares:
y::i as an array of 1 int that will be implicitly zeroed (since all static storage duration objects are zero-initialized if they have no explicit initializer),
y::j as an int with initial value 2,
y::x as struct of type ::x that will be implicitly zeroed, and
y::y is an invalid name. If it was simply y, it would be an int with initial value 0, since its initializer y::x.x is implicitly zero-initialized.
Here's a demo (with y::y changed to y) at Coliru.
NOTE: DO NOT EVER WRITE CODE LIKE THIS. The only time using this feature of names even borders on being acceptable is for member initializers in a class constructor. If you do this anywhere else, I will find you. And I will make you pay.
I think there is some problem with your code. The int y::y = x.x; section is wrong as there is no y previous to this and so this statement needs some correction. I am trying to give some basic info about namespace and its usage, hope it helps.
The main purpose of namespaces is to logically group functionality without the need of long names and the option for handy usage via "using". You can also use same name over different namespaces
namespace Color
{
class Add {};
class Multiply {};
};
namespace Dimension
{
class Add {};
class Multiply {};
};
So you can use the same class name Add, Multiply under two namespaces and one thing which you have to remember is that use namespaces only when required otherwise you will spam the global namespace "std" unknowingly which is not conventional.
For using namespace with inheritance you can search for articles in stack over flow and definitely you will get some. Ex: Accessing Parent Namespace in C++
int i[i]; //line 1
It creates an int array of size 1, as the index i is a constant initialized to 1
int j = j; //line 2
It declares and initilizes a variable j to 2(value of constant j) in a namespace y
x x; //line 3
It creates a structure variable x of type struct x ( Note: The structure variable x is different from the int x present inside the structure x, int x is a member of structure x
int y::y = x.x; //line 4
This is syntactically wrong, there is no need to qualify int y with namespace('y'), as it is already present in the namespaace y, So the statement should be
int y = x.x
where x.x represents accessing the data member (int x) of structure variable x created in the line 3
Namespace example Have a look on this example,it helps you to understand namespaces clearly. Refer the link for more examples [link]http://www.cplusplus.com/doc/tutorial/namespaces/
#include <iostream>
using namespace std;
namespace first
{
int x = 5;
int y = 10;
}
namespace second
{
double x = 3.1416;
double y = 2.7183;
}
int main () {
using namespace first;
cout << x << endl;
cout << y << endl;
cout << second::x << endl;
cout << second::y << endl;
return 0;
}
//Output
5
10
3.1416
2.7183
......Hope it helps you....:)