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 ++;
Related
I found some code similar to this in an example my university tutor wrote.
int main(){
int a=3;
int b=5;
std::vector<int>arr;
arr.push_back(a*=b);
std::cout<<arr[0]<<std::endl;
}
Is there a well-defined behaviour for this? Would arr[0] be 3 or 15 (or something else entirely)?
Visual Studio outputs 15, but I have no idea if that's how other compilers would respond to it.
Before push_back is executed, the expression passed as argument will need to be computed. So what is the value of a *= b. Well it will always be a * b and also the new value of a will be set to that one.
It's valid and works as you expect.
The expression is first evaluated and the result is "returned".
auto& temp = (a*=b);
arr.push_back(temp);
The value of an expression with the compound assignment operator is the value of the left operand after the assignment.
So the code your showed is valid. Moreover in C++ (opposite to C) the result is an lvalue. So you may even write :)
arr.push_back( ++( a *= b ) );
In this case the next statement outputs 16.:)
int main()
{
int x[3]={4,5,6};
int *p=x;
p +1=p;/*compiler shows error saying
lvalue required as left
operand of assignment*/
cout<<p 1;
getch();
}
When you have an assignment operator in a statement, the LHS of the operator must be something the language calls an lvalue. If the LHS of the operator does not evaluate to an lvalue, the value from the RHS cannot be assigned to the LHS.
You cannot use:
10 = 20;
since 10 does not evaluate to an lvalue.
You can use:
int i;
i = 20;
since i does evaluate to an lvalue.
You cannot use:
int i;
i + 1 = 20;
since i + 1 does not evaluate to an lvalue.
In your case, p + 1 does not evaluate to an lavalue. Hence, you cannot use
p + 1 = p;
Put simply, an lvalue is something that can appear on the left-hand side of an assignment, typically a variable or array element.
So if you define int *p, then p is an lvalue. p+1, which is a valid expression, is not an lvalue.
If you're trying to add 1 to p, the correct syntax is:
p = p + 1;
To assign, you should use p=p+1; instead of p+1=p;
int main()
{
int x[3]={4,5,6};
int *p=x;
p=p+1; /*You just needed to switch the terms around*/
cout<<p<<endl;
getch();
}
if you use an assignment operator but use it in wrong way or in wrong place,
then you'll get this types of errors!
suppose if you type:
p+1=p; you will get the error!!
you will get the same error for this:
if(ch>='a' && ch='z')
as you see can see that I i tried to assign in if() statement!!!
how silly I am!!! right??
ha ha
actually i forgot to give less then(<) sign
if(ch>='a' && ch<='z')
and got the error!!
It is just a typo(I guess)-
p+=1;
instead of p +1=p; is required .
As name suggest lvalue expression should be left-hand operand of the assignment operator.
I've been trying to make sense of LLVM's instruction combining code and noticed this function:
static void detectLog2OfHalf(Value *&Op, Value *&Y, IntrinsicInst *&Log2) {
if (!Op->hasOneUse())
return;
IntrinsicInst *II = dyn_cast<IntrinsicInst>(Op);
if (!II)
return;
if (II->getIntrinsicID() != Intrinsic::log2 || !II->hasUnsafeAlgebra())
return;
Log2 = II;
Value *OpLog2Of = II->getArgOperand(0);
if (!OpLog2Of->hasOneUse())
return;
Instruction *I = dyn_cast<Instruction>(OpLog2Of);
if (!I)
return;
if (I->getOpcode() != Instruction::FMul || !I->hasUnsafeAlgebra())
return;
if (match(I->getOperand(0), m_SpecificFP(0.5)))
Y = I->getOperand(1);
else if (match(I->getOperand(1), m_SpecificFP(0.5)))
Y = I->getOperand(0);
}
Why would *& by used in the parameters? Does it have some meaning or would Op be equivalent to *&Op?
Why would *& by used in the parameters?
In a function parameter list, this parameter
IntrinsicInst *&Log2
is a reference to pointer to Value. It means the function can modify the pointer itself, and this is seen at the caller side. In this case, that happens here:
Log2 = II;
If Log2 was not passed by reference, the above line would only have an effect in the scope of the function.
... would Op be equivalent to *&Op?
Not in this context. In a different one, yes. For example, when * is the de-reference operator and & is the address-of operator, then *&x would mean "de-reference the result of applying the address-of operator to x", that is, de-reference a pointer to x. C++ confusingly re-uses symbols depending on context. Most of this is inherited from C. On top of that, changes to C++ should not break existing code. The easiest way to do this is to re-use symbols.
& means reference.
value * means value is a pointer.
value *&op is equalent to passing pointer by reference, so if we change value in the function it will be reflected in the called function.
So I just had a thought, is it possible to return a parameter sent when a function is called. And if it is, is this considered fine or is it bad style?
Example:
int main()
{
...
int value = 1;
value = Foo(value);
...
}
int Foo(int i)
{
i = i * 2;
return (i);
}
As the parameter is being passed in and returned by value, this is fine - there is an implicit copy occurring when you call the function and when it returns.
For example
int value=1,other=0;
other=Foo(value);
other is now 2, value will still be 1
If you were passing in a reference or pointer then you would potentially run risks.
e.g. if the signature of Foo was
int Foo( int &i )
Then after the code chunk I used above, both other and value would be 2
There's no problem with "returning a parameter" in your example. You are not really "returning a parameter" at all. You are simply using the parameter in the argument expression of return. It is the result of that expression (the value of i) that gets returned, not the parameter itself.
One can argue that the "undesirable" property of your code sample is the fact that you are modifying the parameter inside the function, i.e. you are using the parameter as an ordinary local variable. There's nothing formally wrong with it, but sometimes people prefer to preserve the original parameter values throughout the function body. I.e. from that point of view your function would look better as
int Foo(int i)
{
return i * 2;
}
or as
int Foo(int i)
{
int i2 = i * 2;
return i2;
}
but, again, it is not really about "not returning a parameter", but rather about leaving the original value of i untouched inside the function.
There's no problem with doing that and it makes it very clear what's going on.
That's one valid approach to do this, but you might also like the idea of passing by reference:
int main()
{
...
int value = 1;
Foo(value);
...
}
void Foo(int &i)
{
i = i * 2;
}
The drawback to this approach is that you have to pass what's called an lvalue into the function-- basically, something that can be on the left side of an assignment statement, which here means a variable. A call with a literal or temporary, such as Foo(2), will fail to compile. The way you had written it originally will instead do an implicit copy by value into the local scope of the Foo function. Note that the return value is now also void.
Technically, there is no problem, but semantically, it is not advisable: in most cases the input of the function and the return value of the function are not the same, so you are reusing the variable to mean something different. It is clearer in next example
int main()
{
double i = 5;
i = getSquareSurface(i); // i was a length and is now a surface
}
This should be:
int main()
{
double length = 5;
double surface = getSquareSurface(length);
}
Of course, there are cases like the addOne() or in this case the Foo() function where the meaning doesn't change.
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!)