Is there a difference between int x{}; and int x = 0;? - c++

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

Related

What is the compiler doing with parameters vs without parameters? [duplicate]

This question already has answers here:
Undefined, unspecified and implementation-defined behavior
(9 answers)
Closed 4 years ago.
I have a non important question about compilers for C++. The following code outputs
1
2
3
and I can't figure out why. What difference does declaring it with empty parameters make to no parenthesis at all?
#include <iostream>
using namespace std;
int main()
{
int x;
cout << x << endl;
int y();
cout << y << endl;
int z(2);
cout << z << endl;
return 0;
}
The compiler is g++.
The 1st one, x is default initialized with indeterminate value, then cout << x leads to undefined behavior, means anything is possible.
Default initialization of non-class variables with automatic and dynamic storage duration produces objects with indeterminate values
The 2nd one, int y(); declares a function named y, which has no argument and returns int. For cout << y, y will decay to function pointer, which could convert to bool implicitly and then you'll get 1 (i.e. true. You can use std::boolalpha like std::cout << std::boolalpha << y to get the output true).
The 3rd one, z is direct initialized with value 2, then cout << z you'll get 2.
LIVE sample with clang, note all the warning messages the compiler gives.

What is the difference between initializing with = and initializing with {}?

You can initialize a variable using = . For example:
int a = 1000;
C++ 11 introduced an extra notation {} . For example:
int a {1000};
According to Programming: Principles and Practices by Bjarne Stroustrup:
C++11 introduced an initialization notation that outlaws narrowing conversions.
I wanted to check out this cool feature. And I typed a piece of code twice:
#include "std_lib_facilities.h" | #include "std_lib_facilities.h"
|
int main() | int main()
|
{ | {
int x = 254; | int x {254};
char y = x; | char y {x};
int z = y; | int z {y};
|
cout << "x = " << x << '\n' | cout << "x = " << x << '\n'
<< "y = " << y << '\n' | << "y = " << y << '\n'
<< "z = " << z << '\n'; | << "z = " << z << '\n';
|
} | }
The code on the left uses = whereas the code on the right uses {}
But the code on the right hand side loses some information even after using {}. Thus the output is same in both pieces of code:
x = 254
y = ■
z = -2
So, what's the difference between initializing with = and initializing with {} ?
EDIT: My question may or may not be a duplicate. I'm just a beginner and I do not even understand the code of the possibly original question. I'm no judge. Even if it's a duplicate, I cannot understand any answers of that question. I feel that this question should be treated as an original one since I would understand simple language opposed to some high-level words of that question's answer.
What is the difference between initializing with = and initializing with {}?
In general, the difference is that the former is copy initialization and the latter is direct - list initialization. The linked online reference describes all three forms of initialization in detail. In particular, there is the difference that you already quoted; List initialization may not be used with narrowing conversions.
But the code on the right hand side loses some information even after using {}
The program on the right side is ill-formed.
As mentioned, the standard does not allow narrowing conversions in the context of list initialization. int to char is a narrowing conversion.
Because the program is ill-formed, the standard does not guarantee its behaviour except that a compiler is required to emit a diagnostic message. For example, g++-5.3.0 will say:
warning: narrowing conversion of 'x' from 'int' to 'char' inside { } [-Wnarrowing]
May you please elaborate on the "ill-formed" part?
Standard says that the program shall not do X. Your program does X. Therefore it violates the standard which makes the program ill-formed. Here, X is:
If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.
The program on the left is not ill-formed. However it, just like the program on the right side, does assign a value to char y that is not representable by the char type (it could be representable in some implementation where char is an unsigned type, but given the output, that appears not to be the case for your implementation). When an unrepresentable value is converted to a signed type, the resulting value is implementation defined.

c++ Need clear examples showing difference between decltype(x) & decltype((x))

I have read many times on the difference between decltype(x) and decltype((x)). One example is as per below.
x is the name of a variable, so decltype(x) is int. But wrapping the name x in parentheses—“(x)”—yields an expression more complicated than a name. Being a name, x is an lvalue, and C++ defines the expression (x) to be an lvalue, too. decltype((x)) is therefore int&. Putting parentheses around a name can change the type that decltype reports for it!
Can someone show me the output of a variable say x where the output type of decltype(x) and decltype((xx)) are different? I need an example explicitly showing difference in output.
Appreciate that.
Thanks.
If you declare a variable with type decltype((x)), it is a reference. The easiest way to see the difference is probably this:
int x = 0;
decltype(x) copy = x; // creates an int which is a copy of x
decltype((x)) ref = x; // creates a reference to x
ref = 7; // changes x
copy = 99; // does not change x
std::cout << x << '\n'; // prints 7
std::cout << copy << '\n'; // prints 99
std::cout << ref << '\n'; // prints 7
As for when you would use decltype((x)), I hesitate to say never, but I can say that I've never had a reason to do it in my own code.
Let's say we have int a = 0, then decltype(a) would be int, since a directly names the entity. decltype((a)), on the other hand, should be int&, since (a) is an expression that does not refer directly to the entity.
The same holds for members as well, for example:
#include <iostream>
#include <type_traits>
struct S {
int v = 0;
};
int main() {
S s;
std::cout << std::is_same<decltype(s.v), int>() << std::endl;
std::cout << std::is_same<decltype((s.v)), int&>() << std::endl;
}
decltype(s.v) is int, since s.v directly refers to the name of an entity. decltype((s.v)), on the other hand, is int&. (s.v) does not refer directly to the name of the entity.

Strange code... Can someone explain me this

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....:)

Point of declaration in C++

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);