How is this getting evaluated? - c++

I am feeling very stupid to asking this question. but cant figure out the reason on my own.
int main()
{
int target;
int buffer =10;
const int source = 15;
target = (buffer+=source) = 20;
cout << target+buffer;
return 0;
}
target = (buffer+=source) = 20; will become target = (25) = 20.
But if I am giving same statement in my source file, it is giving l-value error.
How the value of target+buffer is printing 40.

Some predefined operators, such as +=, require an operand to be an
lvalue when applied to basic types [§13.5/7]
buffer+=source returns a lvalue reference to buffer. So you have not compile error.
your statement can be evaluate as:
buffer+=source;
buffer=20;
target=20;
But modifying buffer twice in a statement is undefined behavior and another compiler can evaluate something else as result. (Not sure in this case also!)

Related

Applying operations after type conversion error

I have converted using a string into the int. But it has two classes That doesn't have any arithematic or logical operation associated.
string x = "42";
int|error y = int:fromString(x);
y=y+1;
This is by design. When you perform string to int conversion, there can be errors. There is no way the compiler can know beforehand the resulting type. Therefore, the int:fromString() function returns a union type consisting int and the error type.
In Ballerina, there are a couple of ways to handle this. The easiest way is to use the check expression, which is used to early return the error value if an error occurred, and if there's not an error, assign the value to the intended type. Look at the following code:
public function main() returns error? {
string x = "42";
int y = check int:fromString(x);
y += 1; // This is as same as the `y = y + 1;`
}
In the above function, if there's an error in converting the string value to an int value, the error is returned. Otherwise the value is assigned to the variable y. Note that the function has the return type error?, which is a must to use the check expression here.
You can have an error check and do the necessary arithmetic operations in the else block as follows,
string x = "42";
int|error y = int:fromString(x);
if(y is error) {
io:println("Error occurred in conversion");
} else {
y = y + 1;
io:println(y);
}

Issues with assigning result of a function to a variable

#include <iostream>
#include <string>
using namespace std;
int main() {
string userInput;
int stringSize = 0;
userInput = "Hello";
userInput.size() == stringSize;
cout << "Size of userInput: " << stringSize << endl;
return 0;
}
I am trying to get an output of 5, but it is returning 0. I can't figure out what's wrong. The userInput "Hello" should have a size of 5 and userInput.size() should return 5. This should be assigned to variable stringSize. Side note, can anyone explain to me why it is "==" not "="? If I try it with "=", it does not compile and I get this error:
main.cpp: In function ‘int main()’:
main.cpp:11:23: error: lvalue required as left operand of assignment
userInput.size() = stringSize;
^~~~~~~~~~
My understanding is "=" is assignment and "==" is a Boolean comparison that is either "true" or "false" depending on if both sides are equal. I am trying to assign the size of userInput.size() into the variable so I would think that I should use "=". Maybe this is part of the problem?
Here is the answer that was asked for (credits to PacO ):
You always have to put the value that you want to assign to the variable on the right side of the =-operator, and the variable itself to the left side.
What you did, is trying to assign the value of stringSize to userInput.size()
My understanding is "=" is assignment and "==" is a boolean comparison
that is either "true" or "false" depending on if both sides are equal.
Your understanding is correct so far.
I am trying to assign the size of userInput.size() into the variable
so I would think that I should use "="
In general, you cannot write 5 = variable. Left and right in an assignment are not swappable, the order matters.
If you want to assign a value to some variable, the variable must be on the left side of the assignment : variable = 5 .
I used this simplification, but the result of the function size() is like the 5 in my example. This is called a rvalue (like "right-value").
So, in your case, stringSize = userInput.size(); would be correct and set the size of userInput into the variable stringSize (which is called a lvalue a value that can be assigned to, at the left of an assignment).
An lvalue can be seen as a named value that exists past its use, such as a variable. An rvalue doesn't persist past its use, usually the result of a function call or what we'd often refer to as simply a "value".
You can store an rvalue in an lvalue (int i = 2 + 3), but you can't assign an lvalue to an rvalue. That's where your problem exists
The compiler is throwing an error because you have an rvalue userInput.size() and you're treating it as if it's an lvalue by attempting to assign a value to it.
userInput.size() = stringSize
A simpler example would be
int n = 1;
3 = n;
For obvious reasons, you can't just change what 3 is. In your example your function is just returning an integer value...so why should you be able to change that? So you get an error
A different perspective:
You can't set the size of a string. The std::string class automatically calculates the length for you.
So there is no need for the expression:
userInput.size() = stringSize;
To clear the contents of a std::string, use the clear() method:
userInput.clear();
= is an Assignment Operator in C, C++ and other programming languages.
== is assigns the value of right side expression’s or variable’s
value to the left side variable.
Simple example:
int x,y;
x=10;
y=10;
if(x==y)
printf("True");
else
printf("False");
output will be : True
In your case, you have to use one = operator and put function assignment on right of the variable. like this stringSize = userInput.size();
This is the final code:
#include <iostream>
using namespace std;
int main()
{
string userInput;
int stringSize = 0;
userInput = "Hello";
stringSize = userInput.size(); //this line edited.
cout << "Size of userInput: " << stringSize << endl;
return 0;
}
see here online_c++_compiler

Conversion from const int to int giving strange results.Can anyone explain the reason for the strange results

When I tried below code I got strange results.I am trying to change value of constant by using the pointers.But when I output the results pointer value and the original variable variable value its giving two different values.Can anyone explain what exactly happens when explicit conversion take place?
int main()
{
int *p ;
const int a = 20;
p=(int *)&a;
*p = *p +10;
cout<<"p is"<<*p<<"\na is"<<a;
}
output:
p is 30
a is 20
Both C and C++ say that any attempt to modify an object declared with the const qualifier results in undefined behavior.
So as a is object is const qualified, the *p = *p +10; statement invokes undefined behavior.
First of - You really shouldn't be doing this. const is a constant, meaning don't change it! :)
Now to explain what happens (I think):
The space on the stack is allocated for both variables, p and a. This is done for a because it has been referenced by an address. If you removed p, you'd effectively remove a as well.
The number 20 is indeed written to the a variable, and modified to 30 via p, which is what is being printed.
The 20 printed is calculated at compile time. Since it is a const, the compiler optimized it away and replaced with 20, as if you did a #define a 20.
Don't Do That.
If you would write this code in C++ with an explicit cast, you would get something like this:
int main()
{
int *p ;
const int a = 20;
p= const_cast<int*>(&a); // the change
*p = *p +10;
cout<<"p is"<<*p<<"\na is"<<a;
}
Now, this code tells a bit more about what's going on: the constant is cast to a non-constant.
If you are writing a compiler, constants are special variables that are allowed to be 'folded' in the const folding phase. Basically this means that the compiler is allowed to change your code into this:
int main()
{
int *p ;
const int a = 20;
p= const_cast<int*>(&a);
*p = *p +10;
cout<<"p is"<<*p<<"\na is" << 20; // const fold
}
Because you're also using &a, you tell the compiler to put the value 20 in a memory location. Combined with the above, you get the exact results you describe.
This is undefined behavior.
A compiler can assume that nothing is going to change the value of a const object. The compiler knows that the value of "a" is 20. You told the compiler that. So, the compiler actually goes ahead and simply compiles the equivalent of
cout << "p is" << *p << "\na is" << 20;
Your compiler should've also given you a big fat warning, about "casting away const-ness", or something along the same lines, when it tried to compile your code.
Although it is defined as undefined behaviour (as everyone else tells you), it could be that your compiler has allocated a storage location (int) for the const int; that is why the *p= *p + 10 works, but may have repaced a in the output statement with the value 20, as it is supposed to be constant.

the increment of a returned value

I have defined a function like this:
int test(int n) {
const int b = n;
return b;
}
While in the main function, I use like this:
int temp = test(50)++;
And the g++ reports an error:
error: lvalue required as increment operand
Actually, I'm fully confused by this. Would you like to give me some tips or explain it to me.
You can only apply ++ to an lvalue (at least of built-in type). The return value from a function can be an lvalue if if it returns a reference, but otherwise it's an rvalue (in which case, you can't apply ++ to it).
The value returned from test is an rvalue. You cannot use the increment operator (++) on it. You can change your calling code to:
int temp = test(50);
temp++;
or
int temp = test(50) + 1;
Once constant value get intialised you cant not change that value.So its giving error try to execute same function without increamenting const value.
'plusplus' operator is (almost) equivalent to '+= 1' that is 'assign the variable its previous value incremented by one'. The value returned is not a variable, so it can not be the left-side argument of an assignment. That's why the increment operator is not applicable here. Just do
t = test(50) + 1;
or
t = test(50);
t ++;

Strange multiple assignment error in C++

I have multiple assignment statement in my program as shown below where query.constraints.size() is supposed to return 13 (constraints is an array and its returning its size)
int num,size = query.constraints.size();
When I do this size becomes 13 as expected but num becomes 9790272 for some reason.
When I do them separately as below everything is ok and both of them are 13 as expected
int size = query.constraints.size();
int num = query.constraints.size();
Why does my multiple assignment result in a strange a strange value ?
Why does my multiple assignment result in a strange a strange value ?
Because C++ has no multiple assignment1. You are declaring two variables here, but only initialise the second, not the first.
1 Well, you can do int a, b = a = c; but code which does this would be deemed bad by most C++ programmers except in very peculiar circumstances.
You're not assigning multiple times, you're declaring multiple times. You need to do something like:
int num, size;
size = num = query.constraints.size();
A mutiple assignement would looks like:
int num, size;
num = size = query.constraints.size();
But the comma operator does not do a multiple assignement.
What you have is actually a declaration statement, partially with initializer. Your code is equivalent to this code:
int num; // uninitialized, you're not allowed to read it
int size(query.constraints.size()); // initialized
In general, T x = expr; declares a variable x of type T and copy-initializes it with the value of expr. For fundamental types this just does what you expect. For class-types, the copy-constructor is only formally required, but in practice usually elided.
The comma operator doesnt do what you think it does