Using the comma operator in if statements - c++

I tried the following:
if(int i=6+4==10)
cout << "works!" << i;
if(int i=6+4,i==10)
cout << "doesn't even compile" << i;
The first works fine while the second doesn't compile. Why is this?
EDIT: Now I know that the first one may not work as I intend it to. The value of i inside the if scope will be 1, not 10. (as pointed out by one of the comments on this question).
So is there a way to initialize and use a variable inside of an if statement at the same time similar to for(int i=0;i<10;i++)? So that you could produce something like if((int i=6+4)==10) (which will not compile) where the value of I inside the if scope would be 10?
I know you could declare and initialize I before the if statement but is there a way to do this within the statement itself?
To give you an idea why I think this would be usefull.
if(int v1=someObject1.getValue(), int v2=someObject2.getValue(), v1!=v2)
{
//v1 and v2 are visible in this scope
//and can be used for further calculation without the need to call
//someObject1.getValue() und someObject2.getValue() again.
}
//if v1==v2 there is nothing to be done which is why v1 und v2
//only need to be visible in the scope of the if.

The expression used as an initializer expression must be an assignment-expression so if you want to use a comma operator you must parenthesize the initializer.
E.g. (not that what you are attempting makes much sense as 6 + 4 has no side effects and the value is discarded and i == 10 uses the uninitialized value of i in its own initializer.)
if (int i = (6 + 4, i == 10)) // behaviour is undefined
Did you really mean something like this?
int i = 6 + 4;
if (i == 10)
When using the form of if that declares a new variable the condition checked is always the value of the initialized variable converted to bool. If you want the condition to be an expression involving the new variable you must declare the variable before the if statement and use the expression that you want to test as the condition.
E.g.
int i;
if ((i = 6 + 4) == 10)

I doubt seriously either example works to do anything useful. All that it does is evaluate to "true" in a complicated fashions.
But the reason the second one doesn't compile is that it's interpreted as two declarations: int i = 6+4; int i==10 and int i==10 isn't valid because that's an equality operator, not an assignment.

There are different alternatives, because what you want cannot be done (you cannot mix the comma operator with declarations). You could, for example, declare the variable outside of the if condition:
int i = 6+4;
if ( i == 10 ) ...
Or you can change the value of i to be 0 instead of 10 and recalculate i inside the else block:
if ( int i = (6+4)-10 ) ; else {
i += 10;
// ...
}
Much simpler, don't declare the variable at all, since you know the value inside the loop:
if ( (6+4)==10 ) {
int i = 10;
// ...
}
Unless of course you need the value of i in the case where it is not 10, in which case the second option is the most appropriate.

As of C++17 what you were trying to do is finally possible:
if (int i=6+4; i==10)
cout << "works, and i is " << i << endl;
Note the use of ; of instead of , to separate the declaration and the actual condition.

Related

References, Logical Operators, and Loop Condition

I'm having a problem understanding what I'm doing wrong in my code. What I'm trying to do is write a condition for a ternary operator and a do-while loop to recognize if one of my variables is above 1. Well, it is giving me an error that I don't know how to fix. What puzzles me the most is what I'll give an example of shortly. Here's my overall code. Keep in mind I'm a beginner, so there may be things that make you cringe or parts that could be improved.
#include <iostream>
using namespace std;
void getInfo(int&, int&, double&);
int main() {
int ordered, stock;
double charges = 10.00;
getInfo(ordered, stock, charges);
system("pause");
return 0;
}
void getInfo(int& ordered, int& stock, double& charges) {
do {
printf("Enter the amount of spools ordered, in stock, and handling charges: ");
scanf_s("%i %i %lf", &ordered, &stock, &charges);
printf((&ordered > 1 && &stock > 0 && &charges > 0) ? "All added!\n"
: "You messed one up. AGAIN!\n");
} while (&ordered > 1 && &stock > 0 && &charges > 0);
}
Now, the error I'm getting is specifically in the ternary and the while condition. It gives me an error where the > is after ordered for both. Now, if I make it ordered instead of &ordered, the error goes away. Yet, I never get an error for &stock or &charges. I don't know why it's treating &ordered differently. It also doesn't check ordered correctly when I take off the &, for reasons I'm not entirely sure on.
Thank you to whomever is willing to help!
...(&ordered > 1 && &stock > 0 && &charges > 0) ? "All added!\n"
Here, "&ordered" means "the address of the ordered variable. You're obviously not trying to compare the address of ordered, but rather ordered itself. This should be
...(ordered > 1 && stock > 0 && charges > 0) ? "All added!\n"
The same problem is with your while() statement too.
In C++, "&" means two things. In declarations, it's used to declare a reference. In expression, it's the "address of" operator.
Once you declare a reference, like:
int &whatever;
Subsequently, using just whatever refers to the referenced object itself.
: "You messed one up. AGAIN!\n");
The & operator does different things depending on where you put it. If it's in a type declaration (e.g. int& foo), it means that the type is a reference. If however the & is used as an unary operator in an expression it becomes the Address-of operator, and returns a pointer to the object it's used on. So for example int* bar = &spam (assuming spam is an integer) would assign a pointer to spam in in the pointer bar.
Note that reference types behaves identical to the real type. This is perhaps better illustrated with a piece of code:
#include <iostream>
int main() {
int foo = 12;
int& bar = foo; // a reference expects a variable of the same type in the initializer
bar = 24; // Once the reference has been made the variable behaves indentically to the
// to the variable it's a reference to.
std::cout << foo << std::endl; // outputs 24
// if you use the & operator on a reference you get the address the variable it is a
// reference to.
std::cout << &bar << ' ' << &foo << std::endl; // Outputs two equal addresses.
}
There is also a third meaning of & in C++. As the bitwise and operator. foo & bar would result in the bitwise and of the variable foo and bar.

Changing variable name inside a loop

I'm trying to create a loop that will will create a new variable but also change the name of the variable, such as increasing in value, automatically. Not sure if this is possible because you cant have dynamic variables?
if (cin.get() == '\n')
{
m ++; // Add an integer to m
string (1 + m); //Trying to name the string the value of m + 1, i.e 3
cin.ignore():
getline(cin, (1 + m))
myfile << (1 + m) << endl;
}
That is my current code which is full of errors but hopefully readable enough to gain an understanding of what I'm trying to do.
Bad title, don't know what else to call it.
You're misunderstanding C++ if you try to "rename a variable".
C++ is a compiled language in which the names of the variables only exist in your source code as a means of handling them, but not in the compiled program.
You hence can't also create a variable with a specific name at runtime -- variable names simply don't exist then.
You probably want some kind of container that maps values to keys, think of a dictionary, where you can say "for this integer value 12, I store the string monkey" or so. Have a look at std::map.
Now, you're really not making much sense right now; and try to do things that aren't really the way C++ works for anyone who learned it in a ordered manner. I'd really recommend getting a C++ book or tutorial and start with that. It's going to turn out to safe you a lot of time! Here's a list of recommended C++ books and ressources.
You can't. It's not possible in C++.
To declare and initialize a variable in each iteration is however possible:
for (int i = 0; i != 10; ++i) {
int var = i; // Declare 'var' and assign value of 'i' to it.
} // 'var' object goes out of scope and is destroyed
Names are visible from the point where they are declared until the end of the scope in which the declaration appears. Names have scope and Objects have lifetimes.
The closest thing to "renaming" in C++ would be declaring a reference of the "old named" variable with the new name.
int a = 2;
int &b = a;
//you can now call either `b` or `a` to get the value
Creating new variables on the fly is not possible. The correct insert any compiled language name here way of doing it is by pushing values into a container (array, map, stack..etc). With maps, you can do something similar to what you want, but it's different one only "maps" a string to a value.
#include <map>
#include <string>
#include <sstream> //for int to string conversion
std::string stringify(int val)
{
std::stringstream ss;
ss << n;
return ss.str();
}
int main()
{
std::map<std::string, int> values;
for (int i = 0; i < 10; i ++){
values[stringify(i)] = i*100;
}
std::cout << values["1"]; // prints 100
std::cout << values["9"]; // prints 900
return 0;
}

Using declaration in condition part of FOR-loop statement

Reading http://en.cppreference.com/w/cpp/language/for I find, that condition part of for loop can be either expression, contextually convertible to bool, or single-variable-declaration with mandatory brace-or-equal initializer (syntax specification in 6.4/1):
condition:
expression
type-specifier-seq declarator = assignment-expression
But I have never seen a using of the later in a source code.
What is the profitable (in sense of brevity, expressiveness, readability) making use of variable declaration in condition part of for loop statement ?
for (int i = 0; bool b = i < 5; ++i) {
// `b` is always convertible to `true` until the end of its scope
} // scope of `i` and `b` ends here
Variable declared in condition can be only convertible to true during whole period of lifetime (scope) if there no side effects influencing on result of convertion to bool.
I can imagine only a couple of use cases:
declaration a variable of class type, having user-defined operator bool.
some kind of changing cv-ref-qualifiers of loop variable:
for (int i = 5; int const & j = i; --i) {
// using of j
}
But both of them are very artifical.
All three statements if, for and while can be used in a similar way. Why is this useful? Sometimes it just is. Consider this:
Record * GetNextRecord(); // returns null when no more records
Record * GetNextRecordEx(int *); // as above, but also store signal number
// Process one
if (Record * r = GetNextRecord()) { process(*r); }
// Process all
while (Record * r = GetNextRecord()) { process(*r); }
// Process all and also keep some loop-local state
for (int n; Record * r = GetNextRecordEx(&n); )
{
process(*r);
notify(n);
}
These statements keep all the variables they need at the minimal possible scope. If the declaration form wasn't allowed inside the statement, you would need to declare a variable outside the statement but you would only need it for the duration of the statement. That means you would either leak into too large a scope, or you would need unsightly extra scopes. Allowing the declaration inside the statement offers a convenient syntax, which although rarely useful is very nice to have when it is useful.
Perhaps the most common-place use case is in a multiple-dispatch cast situation like this:
if (Der1 * p = dynamic_cast<Der1 *>(target)) visit(*p);
else if (Der2 * p = dynamic_cast<Der2 *>(target)) visit(*p);
else if (Der3 * p = dynamic_cast<Der3 *>(target)) visit(*p);
else throw BadDispatch();
As an aside: only the if statement admits a code path for the case where the condition is false, given in an optional else block. Neither while nor for allow you to consume the result of the boolean check in this way, i.e. there is no for ... else or while ... else construction in the language.

Why is the following code illegal in C++ [duplicate]

This question already has answers here:
Declaring and initializing a variable in a Conditional or Control statement in C++
(9 answers)
Closed 7 years ago.
I want to create an if where a variable is declared, assigned and checked. If the variable's value is acceptable, I want to use it inside if body. Here's an example of how I thought I could do that:
if ((int result = Foo()) != 0) {
// use result
}
I assumed that Foo() returns some value, which is assigned to result, and returned by assignment operator =, and finally checked against 0 in != 0. Unfortunately, it results in a compilation error:
main.cpp:31:10: error: expected primary-expression before ‘int’
if ((int i = Foo()) != 0)
^
main.cpp:31:10: error: expected ‘)’ before ‘int’
Why is this error happening? And what ways could there be to fix it?
The logic is supported, but declaring a variable within an if statement and using it this way is not. The reason is related to the fact that an initializer works differently than a regular assignment, but working around this is easy and trivial.
Just do something like this instead.
int result;
if ((result = Foo()) != 0) {
// use result
}
Your reasoning seems to be based on the assumption that = in
if ((int result = Foo()) != 0)
is an assignment operator and that int result = Foo() is "just an expression" that evaluates to something.
This is not true.
The int result = Foo() part is not an expression in C++. It is a declaration with an initializer. The = in initializer syntax is not an assignment operator at all. It is just a syntactic element that coincidentally uses the same character as assignment operator. The int result = Foo() is not an expression and it does not "evaluate" to any result.
Because if the above, support for something like
if (int result = Foo())
requires special treatment, which severely limits the flexibility of this syntax. What you tried in your code goes outside the bounds of what's allowed by that special treatment.
Bjarne uses this construct as a scope restrictor in 6.3.2.1 The C++ programming language as a recommendation.
Use:
if (int result = Foo()) {
// use non-zero result
}
It is particularly useful with pointers
if (Foo* result = GetFoo()) {
// use valid Foo
}
The !=0 part is redundant as truthiness is !=0.
The extended construct with the comparison is not allowed.
Further discussion of this construct from here
It fails because it's illegal. It's also ugly. #Jonathan Wood suggested declaring the variable outside the if. I suggest calling Foo outside, too:
int result = Foo();
if(result!=0) ...
The (x=f())!=y construct, while legal as an if condition, only makes sense in a loop, where
`while((c=getchar())!='\n)
... do something with c ...
Is the shorter and nicer equivalent of
c = getchar();
while(c!='\n')
{
...
c = getchar(c);
}
It saves writing the call to getchar() twice. It saves nothing when used in an if, so there's no point in using it.
Try this:
if ( int i = (Foo() != 0) ? Foo() : 0 ){
cout << "Hello. Number i = " << i;
}

Decrement Operator in C++

I am from C background, and now I am learning OOP using C++
Below is a program that calculates factorial.
#include <iostream>
using namespace std;
void main ()
{
char dummy;
_int16 numb;
cout << "Enter a number: ";
cin >> numb;
double facto(_int16);
cout << "factorial = " <<facto(numb);
cin >> dummy;
}
double facto( _int16 n )
{
if ( n>1 )
return ( n*facto(n-1) );
else
return 1;
}
The above code works fine.
But if I replace the return statement
return ( n*facto(n-1) );
with this
return ( n*facto(n--) );
then it doesn't work. The n-- won't decrement n by 1. Why?
I am using Visual Studio 2012
Edit:Got it! thanks :)
*also, I would like to add to the answers below: using --n will cause the n to decrement before the statement is executed. So, due to pre-decrement, the expression will become (n-1)*facto(n-1) . That is why it is better not to use pre-decrement in this case *
Currently, by using n-- you are passing the original and therefore unmodified value of n into facto which is causing a loop.
You need to use n - 1 instead. It would, on the face of it, be tempting to use --n since that would decrement n and evaluate to the new (lower) value. But --n will give you undefined behaviour since you are pre-multiplying the function return value by n and since * is not a sequence point, the value of n is not well-defined.
(By the way, the behaviour in C would have been identical).
[Edit: acknowledge Mike Seymour on the undefined behaviour point].
EDIT:: The explanation below is only to shed light on the usage of Post and Pre-Decrement for OP's better understanding of them. The correct answer for OP's code is, n*facto(n - 1). #OP: You should not do any pre-drecrement in that part of your code because it will invoke Undefined Behavior due to unsequenced modification of variable n.
Pre And Post-Decrement::
You have to use pre-decrement (wiki-link) if you want to decrement the variable before the value is passed. On the other hand, a post-decrement evaluates the expression before the variable is decremented:
int n = 10, x;
x = --n; // both are 9
and
int n = 10, x;
x = n--; // x = 10, i = 9
Why not to use pre-decrement in your case?:: n*facto(n--) causes UB.
Why?
The Standard in §5/4 says
Between the previous and next sequence point a scalar object shall
have its stored value modified at most once by the evaluation of an
expression.
and
The prior value shall be accessed only to determine the value to be
stored.
It means, that between two sequence points a variable must not be modified more than once and, if an object is written to within a full expression, any and all accesses to it within the same expression must be directly involved in the computation of the value to be written.
return ( n*facto(n--) );
You are using the post decrement operator.
What happens is, You pass the value of n to the function and then decrement it. That doesn't affect the value that is already passed to the function