Preference on initialising variables in C++ - c++

Starting out in c++ and noticed that you could initialise a variable in two ways
int example_var = 3; // with the assignment operator '='
or
int example_var(3); // enclosing the value with parentheses
is there a reason to use one over the other?

The first form dates back from the C time, while the second was added in C++. The reason for the addition is that in some contexts (in particular initializer lists in constructors) the first form is not allowed.
The two are not exactly equivalent for all types, and that is where one or the other might be more useful. The first form semantically implies the creation of a temporary from the right hand side, followed by the copy construction of the variable from that temporary. The second form, is direct initialization of the variable from the argument.
When does it matter?
The first form will fail if there is no implicit conversion from the right hand side to the type of the variable, or if the copy constructor is not available, so in those cases you will have to use direct initialization.
The second form can be used in more contexts than the first, but it is prone to the most-vexing-parse. That is, in some cases the syntax will become compatible with a declaration for a function (rather than the definition of a regular variable), and the language determines that when this is the case, the expression is to be parsed as a function declaration:
std::string s = std::string(); // ok declares a variable
std::string s( std::string() ); // declares a function: std::string s( std::string(*)() )
Finally in C++11 there is a third form, that uses curly braces:
std::string s{std::string{}};
This form has the advantages of direct initialization with parenthesis, but at the same time it is not prone to misinterpretation.
Which one to use?
I would recommend the third option if available. That being said, I tend to use the first more often than not, or the second depending on the context and the types...

For built in types like int both mean the same.
But for custom data types they can mean different. First format is called Copy Initialization while second is called Direct Initialization.
Good Read:
Is there a difference in C++ between copy initialization and direct initialization?

Their output is the same...
the both the syntax call the copy constructor.
It is same for int and other similar built in data types, though some difference is there for user defined data types.

They compile to the same thing. However, both are a form of variable initialization, not assignment, which matters a little in C and a lot in C++ since totally different functions (constructor v. assignment) are called.

Related

How to control when initializer_list is used. Local vars, returning, and passing args

When writing code, I'm usually very clear in my own mind about whether or not I want to call a constructor that has a single initializer_list constructor. But I often don't feel confident when writing code that I can specify what will happen. There appear to be changes planned for c++17, around auto, which simply add to my paranoia. I don't want to understand all the corners cases to understand everybody else's code. I just hope to fix some simple rules for writing code.
Ideally, an answer would have two parts: "If you want the init-list constructor, do X1,Y1,Z1. But if you don't want it, then do X2,Y2,Z2. If you read code that doesn't clearly follow one of these patterns exactly, then things get complicated and you could consider rewriting "
Pre-question: Is there a convenient name for constructors that have exactly one argument, which is of type std::initializer_list<T>? This constructor appears to be 'special', so it should have a clear name.
Are there any simple rules-of-thumb to ensure that the desired behaviour is achieved? Perhaps something like:
(This is just a hypothetical list, probably incorrect)
a return followed by a { will always call the init-list constructor (if present)
in a variable definition, = followed by { will also prefer the init-list constructor
foo(3, ???, true) will construct the second arg of foo as an init-list if ??? takes this form (beginning with { I guess)
And of course, I also would like to be able to do the opposite consistently. If returning a vector<int> for example, how do I return in such a way that I get the non-init-list constructors? (And also avoid the most-vexing-parse, of course!).
I can see three scenarios where this is relevant. Initializing variables in a function, returning from a function, and passing args to a function. And I guess there are other interesting places too.
If we can identify a few non-ambiguous patterns that cover all these use-cases, which behave the same in c++11/14/17, then I would simply avoid any code that doesn't match that pattern and replace it with something that is clear to me.
If you want the init-list constructor, do X1,Y1,Z1.
The only way to guarantee, for an arbitrary type, the use of an initializer_list constructor (with compilation failure if no such constructor exists) is to actually specify that to the braced-init-list:
T v(std::initializer_list<int>{...});
If you didn't have the std::intializer_list part there, then your braced-init-list might have initialized the first parameter as being of some other type.
But if you don't want it, then do X2,Y2,Z2.
The only way to guarantee, for an arbitrary type and for arbitrary arguments, the calling of a non-initilaizer_list constructor is to not use braced-init-lists at all. std::allocator<T>::construct does this, for example.
T v(...);
If you use a braced-init-list at all, for an arbitrary type, then you run the risk of calling the wrong kind of constructor.
If you read code that doesn't clearly follow one of these patterns exactly, then things get complicated and you could consider rewriting
That's up to you, but the fact is other people are not going to give up braced-init-lists just because they might be confusing in some corner cases.
Remember: the problems you're talking about only arise when dealing with an unknown type: some arbitrary T or a container of an arbitrary T or whatever. While there is plenty of template code that deals in arbitrary types T, there's plenty of code that doesn't as well. Most of the time, it is very well understand what a particular braced-init-list will do.
So no, there is no rule which, if not followed, "you could consider rewriting" the code in question. Other people are not going to follow these draconian rules, simply because there are places where you have to be careful when using braced-init-lists.
Now, do I wish that we had a language feature that would allow you to specify if a braced-init-list could call an initializer_list constructor or not? Absolutely. But that ship sailed 5 years ago, and tons of code has been written since then.
If we had to write a macro to take a type T, a variable name v, and a set of parameters, and you wanted to avoid the init-list constructor and also avoid the most vexing parse, how would we write it?
The most-vexing-parse primarily shows up because you want to default-construct some temporary:
K k(T()); //Declares a function.
Therefore, if you wish to avoid this, use braced-init-lists for default construction:
K k(T{});
So users of your macro will have to do the same. That is, it is on the user to use {} for any default-constructed temporary objects. There is nothing your macro can do to prevent it.
TLDR: Embrace the ( parentheses ).
There are two sides to this question. First, if an initializer-list constructor exists and we want to call it, what should we write? Second, how to we avoid such a constructor and call some other constructor that exists? A famous example of the second case is vector, which has a two-arg constructor vector::vector(size_t, T init) which seems difficult to call in the new regime.
1. Calling the the init-list constructor consistently:
Use ({ and }). This will call the init-list constructor, where it exists. It can even pass an empty list, so there's no "empty list exception" whereby the default constructor is called instead. Even though { is known to be quite "greedy", calling the init-list constructor quite readily, it will (surprisingly?) prefer to call the default constructor if one is available. The greediest (concise) form that I am aware of is ({:
X x({}); // passes an empty init-list
X x({1}); // passes a one-element init-list
X x({1,2}); // passes a two-element init-list
auto x = X({}); // as above
auto x = X({1}); // as above
auto x = X({1,2}); // as above
(I must admit that, in the particular case of an empty list, I guess the default constructor probably is a perfectly fine choice. I can't imagine a real situation where I'd really prefer to force the init-list constructor to be used with an empty list.)
2. Avoiding the init-list constructor
We can't use { because they are greedy, so just use (. If you're scared of the most-vexing-parse (you should be!), then just ensure you always use this in an auto declaration
auto x = X( ) ; // default constructor
auto x = X( 1 ); // one-arg non-init-list constructor
auto x = X(1,2); // two-arg non-init-list constructor
auto v = std::vector<int>(5,0); // five elements, not two. As desired
Basically, to solve the most vexing parse, use auto instead of switching ( to {.
Finally, you also asked about return. This doesn't appear to be a straightforward issue. Reliably selecting a constructor to be used requires putting the type explicitly in the return statement, which can be inconvenient. (I wish there was a decltype(return), which could only be used in return statements, to tell us the return type. Allowing return decltype(return)({1,2,3});)
PS: calling functions is slightly more annoying than in needs to be, when it comes to cleanly selecting the desired constructor of the parameter. I wish it was possible to calling a function like this:
// wish-list code, not supported
foo(
{} // create first arg with default constructor
,{1} // create second arg with one-arg non-init-list constructor
,{5,'x'} // if the third arg is of type vector<char>, for example
,{{}} // construct fourth arg with an empty init list
,{{1}} // construct fifgh arg with an one-element init list
,{{1,2}} // construct sixth arg with a two-element init list
);
But, this is impossible now. With a time machine, and a small change to the original spec, this could all be a lot cleaner.

Will using brace-init syntax change construction behavior when an initializer_list constructor is added later?

Suppose I have a class like this:
class Foo
{
public:
Foo(int something) {}
};
And I create it using this syntax:
Foo f{10};
Then later I add a new constructor:
class Foo
{
public:
Foo(int something) {}
Foo(std::initializer_list<int>) {}
};
What happens to the construction of f? My understanding is that it will no longer call the first constructor but instead now call the init list constructor. If so, this seems bad. Why are so many people recommending using the {} syntax over () for object construction when adding an initializer_list constructor later may break things silently?
I can imagine a case where I'm constructing an rvalue using {} syntax (to avoid most vexing parse) but then later someone adds an std::initializer_list constructor to that object. Now the code breaks and I can no longer construct it using an rvalue because I'd have to switch back to () syntax and that would cause most vexing parse. How would one handle this situation?
What happens to the construction of f? My understanding is that it will no longer call the first constructor but instead now call the init list constructor. If so, this seems bad. Why are so many people recommending using the {} syntax over () for object construction when adding an initializer_list constructor later may break things silently?
On one hand, it's unusual to have the initializer-list constructor and the other one both be viable. On the other hand, "universal initialization" got a bit too much hype around the C++11 standard release, and it shouldn't be used without question.
Braces work best for like aggregates and containers, so I prefer to use them when surrounding some things which will be owned/contained. On the other hand, parentheses are good for arguments which merely describe how something new will be generated.
I can imagine a case where I'm constructing an rvalue using {} syntax (to avoid most vexing parse) but then later someone adds an std::initializer_list constructor to that object. Now the code breaks and I can no longer construct it using an rvalue because I'd have to switch back to () syntax and that would cause most vexing parse. How would one handle this situation?
The MVP only happens with ambiguity between a declarator and an expression, and that only happens as long as all the constructors you're trying to call are default constructors. An empty list {} always calls the default constructor, not an initializer-list constructor with an empty list. (This means that it can be used at no risk. "Universal" value-initialization is a real thing.)
If there's any subexpression inside the braces/parens, the MVP problem is already solved.
Retrofitting classes with initializer lists in updated code is something that sounds like it will be a common thing to happen. So people start using {} syntax for existing constructors before the class is updated, and we want to automatically catch any old uses, especially those used in templates where they may be overlooked.
If I had a class like vector that took a size, then arguably using {} syntax is "wrong", but for the transition we want to catch that anyway. Constructing C c1 {val} means take some (one, in this case) values for the collection, and C c2 (arg) means use val as a descriptive piece of metadata for the class.
In order to support both uses, when the type of element happens to be compatible with the descriptive argument, code that used C c2 {arg} will change meaning. There seems to be no way around it in that case if we want to support both forms with different meanings.
So what would I do? If the compiler provides some way to issue a warning, I'd make the initializer list with one argument give a warning. That sounds tricky not to mention compiler specific, so I'd make a general template for that, if it's not already in Boost, and promote its use.
Other than containers, what other situations would have initializer list and single argument constructors with different meanings where the single argument isn't something of a very distinct type from what you'd be using with the list? For non-containers, it might suffice to notice that they won't be confused because the types are different or the list will always have multiple elements. But it's good to think about that and take additional steps if they could be confused in this manner.
For a non-container being enhanced with initializer_list features, it might be sufficient to specifically avoid designing a one-argument constructor that can be mistaken. So, the one-arg constructor would be removed in the updated class, or the initializer list would require other (possibly tag) arguments first. That is, don't do that, under penalty of pie-in-face at the code review.
Even for container-like classes, a class that's not a standard library class could impose that the one-arg constructor form is no longer available. E.g. C c3 (size); would have to be written as C c3 (size, C()); or designed to take an enumeration argument also, which is handy to specify initialized to one value vs. reserved size, so you can argue it's a feature and point out code that begins with a separate call to reserve. So again, don't do that if I can reasonably avoid it.

Non-POD object error

So, I've read a lot online for this error, but for some reason, I'm still getting it even after I have tried the suggested things. If anyone could help me understand this and point out what's wrong, that would be awesome.
char * s = strtok(text, ",");
string name = s;
printf("%s", name);
Given your example code the error you get is saying something like you cannot pass a non-POD object to an ellipses. This is because you are trying to pass a non-POD type to a variadic function, one that takes a variable number of arguments. In this case by calling printf which is declared something like the below
int printf ( const char * format, ... );
The ellipsis used as the last parameter allows you to pass 0 or more additional arguments to the function as you are doing in your code. The C++ standard does allow you to pass a non-POD type but compilers are not required to support it. This is covered in part by 5.2.2/7 of the standard.
Passing a potentially-evaluated argument of class type having a non-trivial copy constructor, a non-trivial move contructor, or a non-trivial destructor, with no corresponding parameter, is conditionally-supported with implementation-defined semantics.
This means it is up to each compiler maker to decide if they want to support it and how it will behave. Apparently your compiler does not support this and even if it did I wouldn't recommend using it.

C++(11): When to use direct or copy initialization if both are perfectly fine

Before the shouts for duplicate begin: I am aware that the following question (and some others) are quite related to this one:
Is there a difference in C++ between copy initialization and direct initialization?
The answers in this question perfectly explains scenarios where copy initialization is not possible and explains the difference of the two and all that stuff. However, my question is more subtle:
Consider the code:
A createA(){...}
A a1 = createA();
A a2(createA());
Assume that A can be implicitly copy constructed and all that stuff, so both initializations of a1 and a2 are fine. There are no side effects in the copy constructor for A, so both initializations are also semantically equivalent. createA() returns directly the type of the variable, not something else that has to be cast first. I think this case is quite common.
So, in this case, where both alternatives are equally applicable and semantically equivalent, which one should I use? Is there a recommendation in the spec or a consensus/best practice in the community or is it just up to me and my coding style which one to use? Has C++11 introduced any difference in comparison to older standards?
If everything else is equal (semantics, performance,...) it's obviously only a matter of taste and/or style convention. However, many authors advocate a list-initializer for direct initialization these days:
A a3 {createA()};
But I'd say it's either up to you (if it's your fun project) or to your coworkers to decide on one of the two (three) alternatives. I would not recommend to use both interchangeably, because that would make readers wonder why you use sometimes direct and sometimes copy initialization.
There's no "always better" answer, it's a matter of style.
When initializing an object from a simple expression of the object's type (such as createA()) I often use copy-init, probably just due to familiarity with the = form of assignment. Otherwise, when the initializer is a different type or there are multiple initializers for the object (e.g. multiple constructor arguments, or aggregate init) I prefer to use C++11 list-initialization (a.k.a uniform initialization syntax), which can be used in more places, e.g. to initialize aggregates as well as classes with user-defined constructors, and cannot be parsed as a function declaration:
A a1{ createA() };
The above form of list-init uses direct-init, whereas this form uses copy-init:
A a2 = { createA() };
When using list-init I prefer the direct-init form without the redundant = sign.
There are a few cases where list-init isn't possible, e.g. when a type has an initializer-list constructor (i.e. one taking a parameter that is a specialization of std::initializer_list) and you want to call a different constructor, but the initializer-list constructor would get chosen, e.g. std::vector<int> v{ 5u, 0 }; will not create a vector of five elements with value zero, but a vector with two elements with values five and zero

What is the name and reason for member variable assignment between function name and curly braces?

Look at this code snippet:
Size::Size(int iSetWidth, int iSetHeight)
:iWidth(iSetWidth),
iHeight(iSetHeight)
{
}
Supposedly, this means the same thing as:
Size::Size(int iSetWidth, int iSetHeight)
{
iWidth=iSetWidth;
iHeight=iSetHeight;
}
Why would you use the former or the latter? And what is the name of the former?
No, they don't mean exactly the same.
When a constructor is executed, before entering the code block (the code between the curly braces), it constructs all object data members. What you do in the initializers (the code after the colon and before the curly braces) is to specify which constructors to use for those members. If you don't specify a constructor for a specific data member, the default constructor will be used.
So, if you use the initialization list (first example), the right constructors will be used for each member and no additional code is necessary. If you don't, first the default constructor is used and then the code inside the curly braces is executed.
In summary:
In your first example, each member is initialised using the appropriate constructor, probably the copy constructor.
In your second example, each member is constructed using the default constructor, and then some additional code is executed to initialise it, probably the assignment operator.
EDIT: Sorry, forgot to answer your questions in the last line.
The name of the code between the colon and the curly braces is initialisation list.
If you know which is the right constructor for a variable or data member, by all means use it. This is the reason why most classes have different constructors instead of just a default constructor. So you are better off using the initialization list.
The initialisation list is almost never slower than the other technique, and can easily be faster. A well known rule when writing code is "don't optimize prematurely", but there is a not so well known counterpart: don't pessimize prematurely. If you have two options for writing a piece of code and one of them can be better than the other, but does not involve additional work or complexity, use it. In your example there is no difference, since you are using a built-in type (int). But if you were using classes, there would be a difference, so get used to the initialization list.
THe former is called initilazation lists.
You can get plentyof articles for that.
The particular reasons for using intializer lists are given here
http://www.learncpp.com/cpp-tutorial/101-constructor-initialization-lists/
You can refer Effective C++ to get full insight into intializer lists.
Hope it is clear.
BTW, Bjarne Stroustrup said in The C++ Programming Language that some efficiency may be gained with initialization list and he recommended us to use initialization list!