compilation error

S

somenath

Hi ALL,

I have one doubt regarding the compilation error for the bellow
mentioned code.

#include<stdio.h>
int main(void)
{
int a =5,b=0;
a>5?b=3:b=5;
printf("\n Value of B = %d \n",b);
return 0;

}
Compilation Error

tarnarytest.c: In function `main':
tarnarytest.c:5: invalid lvalue in assignment.

Could any body tell me why is it throwing this error ?


Regards,
Somenath
 
I

Ian Collins

somenath said:
Hi ALL,

I have one doubt regarding the compilation error for the bellow
mentioned code.

#include<stdio.h>
int main(void)
{
int a =5,b=0;
a>5?b=3:b=5;

Why not just write

b = a>5 ? 3 : 5;
 
S

somenath

Why not just write

b = a>5 ? 3 : 5;

But If i change my code as mentioned bellow I am not getting
compilation error
#include<stdio.h>
int main(void)
{
int a =5,b=0;
a>5?b=3:(b=5);
printf("\n Value of B = %d \n",b);
return 0;

}
~
but i am not understanding why ?
 
K

Keith Thompson

somenath said:
I have one doubt regarding the compilation error for the bellow
mentioned code.

#include<stdio.h>
int main(void)
{
int a =5,b=0;
a>5?b=3:b=5;
printf("\n Value of B = %d \n",b);
return 0;

}
Compilation Error

tarnarytest.c: In function `main':
tarnarytest.c:5: invalid lvalue in assignment.

Could any body tell me why is it throwing this error ?

The biggest problem with the line

a>5?b=3:b=5;

isn't that it's illegal, it's that it's *ugly*. Whatever you're
trying to do, there's certainly a better and more legible way to do
it.

For starters, adding whitespace around operators can make things much
easier to read:

a > 5 ? b = 3 : b = 5;

Well, it usually does, but in this case it doesn't help all that much.
What you really need is parentheses.

The key thing here is that the trinary '?:' operator binds more
tightly than the assignment operator. I *think* that the above is
equivalent to:

(a > 5 ? b = 3 : b) = 5;

which attempts to use a conditional expression as the left side of an
assignment. Since the result of a conditional expression is not an
lvalue, this is illegal.

I think what you're trying to do is:

(a > 5) ? (b = 3) : (b = 5);

so adding the parentheses as I've done here is one solution. A slightly
better solution is:

b = (a > 5 ? 3 : 5);

but an even better one is:

if (a > 5) {
b = 3;
}
else {
b = 5;
}

If you insist, you can omit the braces:

if (a > 5)
b = 3;
else
b = 5;

but that can cause problems if you later find that you need to add
more statements.

C has more than a dozen levels of operator precedence. Just by using
an 'if' statement, you avoid having to worry about *any* of them, and
you get code whose meaning is obvious at a glance.

If you're using the '?:' operator where an 'if' statement would do the
job just as well, use an 'if' statement. If you're using multiple
operators in an expression and you're not certain of the precedence,
add parentheses until it's clear what the expression actually means.
I wouldn't bother with parentheses in

a = b + c * d;

but if I have to look up the precedence in a book, the expression is
too obscure. There is no virtue in obfuscation (unless you're
entering the International Obfuscated C Code Contest; see
<http://www.ioccc.org/>).

There are cases where you actually need to use '?:' rather than 'if',
particularly where you need an expression rather than a statement in a
macro definition. But even in that case, clarity is still important.
 
C

Chris Dollin

Keith said:
I think what you're trying to do is:

(a > 5) ? (b = 3) : (b = 5);

so adding the parentheses as I've done here is one solution. A slightly
better solution is:

b = (a > 5 ? 3 : 5);

but an even better one is:

if (a > 5) {
b = 3;
}
else {
b = 5;
}

Don't be ridiculous.

Really. Five additional lines, and obscuring that the point is to assign to
`b`, and that `a` just selects the value to be assigned? That's not /better/;
that's some kind of anti-trinary space-burning obsession. Isn't it?

The one-liner says what it means, and means what it says. I have no idea
why anyone -- especially Keith -- would think the if-statement form better.
 
M

Mark Bluemel

But If i change my code as mentioned bellow I am not getting
compilation error
#include<stdio.h>
int main(void)
{
int a =5,b=0;
a>5?b=3:(b=5);
printf("\n Value of B = %d \n",b);
return 0;

}
~
but i am not understanding why ?

Keith discusses this in detail in his post - you are hitting issues with
operator precedence.

This is, in my opinion and in part. a by-product of your poor
understanding of the ternary operator - it is intended to work with
expressions not statements (I'm disregarding that "b=3" is also an
expression, in this context we are not looking at its value).

As others have said, "b = a>5?3:5;", possibly decorated with whitespace
and/or parentheses, is safer and clearer. It is also, in my view, more
in accord with the intent of the language designers.
 
A

Army1987

But If i change my code as mentioned bellow I am not getting
compilation error
#include<stdio.h>
int main(void)
{
int a =5,b=0;
a>5?b=3:(b=5);
printf("\n Value of B = %d \n",b);
return 0;

}
~
but i am not understanding why ?
Because a > 5 ? b = 3 : b = 5 means (a > 5 ? b = 3 : b) = 5.
You can't assign to the result of a ternary operator.
 
P

pete

Keith Thompson wrote:
For starters, adding whitespace around operators can make things much
easier to read:

a > 5 ? b = 3 : b = 5;

Well, it usually does, but in this case it doesn't help all that much.
What you really need is parentheses.

The key thing here is that the trinary '?:' operator binds more
tightly than the assignment operator. I *think* that the above is
equivalent to:

(a > 5 ? b = 3 : b) = 5;

which attempts to use a conditional expression as the left side of an
assignment. Since the result of a conditional expression is not an
lvalue, this is illegal.

I think what you're trying to do is:

(a > 5) ? (b = 3) : (b = 5);

so adding the parentheses as I've done here is one solution.

As a point of trivia,
the middle operand of the conditional operator,
never needs parentheses,
since ? and : can only exist in matched pairs,
the way that ( and ) do.

(a > 5) ? b = 3 : (b = 5);
 
C

Christopher Benson-Manica

Keith Thompson said:
so adding the parentheses as I've done here is one solution. A slightly
better solution is:
b = (a > 5 ? 3 : 5);

A significantly better solution would be

b = a > 5 ? 3 : 5;

, with spacing variations according to one's religion. I don't view
the parentheses as enhancing clarity at all.
C has more than a dozen levels of operator precedence. Just by using
an 'if' statement, you avoid having to worry about *any* of them, and
you get code whose meaning is obvious at a glance.

And you can avoid worrying about the precedence of && and || by
replacing


if( foo || bar && baz ) {
/* ... */
}

with

if( foo ) {
/* ... */
}
else if( bar && baz ) {
/* same stuff */
}

, but no one would do this, because an understanding of the precedence
of && and || is viewed as prerequisite to programming in C. 'if'
should not be viewed as a universally preferable substitute for
a reasonable understanding of operator precedence.
but if I have to look up the precedence in a book, the expression is
too obscure.

I have a hard time believing that you had to look up

b = a > 5 ? 3 : 5;

in a book.
 
C

CBFalconer

Chris said:
Keith Thompson wrote:
.... snip ...

Don't be ridiculous.

Really. Five additional lines, and obscuring that the point is to
assign to `b`, and that `a` just selects the value to be assigned?
That's not /better/; that's some kind of anti-trinary space-burning
obsession. Isn't it?

You could be simple with:

b = 5;
if (a > 5) b =3;

which is clear, and the optimizer might reduce it to almost zero.
 
A

August Karlstrom

Christopher Benson-Manica skrev:
[...]
And you can avoid worrying about the precedence of && and || by
replacing


if( foo || bar && baz ) {
/* ... */
}

with

if( foo ) {
/* ... */
}
else if( bar && baz ) {
/* same stuff */
}

, but no one would do this, because an understanding of the precedence
of && and || is viewed as prerequisite to programming in C.

Or rather because of the code duplication it leads to.


August
 
O

Old Wolf

The biggest problem with the line

a>5?b=3:b=5;

isn't that it's illegal, it's that it's *ugly*.

Being illegal is a bigger problem, IMHO
I think what you're trying to do is:
(a > 5) ? (b = 3) : (b = 5);

Let's not forget the old:
b = 3 + 2 * !(a > 5);
 
K

Keith Thompson

Old Wolf said:
Being illegal is a bigger problem, IMHO

It depends on how you look at it. Illegal but non-ugly code is easier
to fix than illegal and ugly code.

[snip]
 
C

Chris Dollin

CBFalconer said:
You could be simple with:

b = 5;
if (a > 5) b =3;

which is clear,

Less clear than the single expression it replaces. Why do you think
it's clearer to say "set b to some value. Now if some condition
is true, set it to a different one" than to say "set b to a value;
either this one or that one, depending".
and the optimizer might reduce it to almost zero.

I'm not making arguments about optimisation.
 
R

Richard

Keith Thompson said:
so adding the parentheses as I've done here is one solution. A slightly
better solution is:

b = (a > 5 ? 3 : 5);

but an even better one is:

if (a > 5) {
b = 3;
}
else {
b = 5;
}

I would strongly disagree.

The first line is easy to read and succinct.

If a nOOb doesn't know about it, they can learn and its then second
nature.

use the features of the language.
 
K

Keith Thompson

Richard said:
I would strongly disagree.

The first line is easy to read and succinct.

If a nOOb doesn't know about it, they can learn and its then second
nature.

use the features of the language.

Ok, I seem to be in the minority on this question.

On further thought, I don't mind the
b = (a > 5 ? 3 : 5);
form so much; I may have gotten a little carried away in my previous
response. But I still tend to prefer 'if' over '?:' in most cases.

There's certainly a lot of code that abuses the '?:' operator where an
if statement would be clearer, even if 'b = (a > 5 ? 3 : 5);' isn't
necessarily a good example.
 
R

Richard Tobin

Keith Thompson said:
On further thought, I don't mind the
b = (a > 5 ? 3 : 5);
form so much; I may have gotten a little carried away in my previous
response. But I still tend to prefer 'if' over '?:' in most cases.

One reason not often mentioned for using ?: in a case like this is
that it more accurately expresses the intention. The choice does not
involve whether to assign to a - that happens in both cases. The
choice is between values to assign, so it is natural that the conditional
should be around the rhs only.

In a (common) case like

a = (a > max ? max : a)

the same argument suggests that you should use an if. Using ?:
conceals the fact that you really only want to modify a if it's too
big.

-- Richard
 
R

Richard

One reason not often mentioned for using ?: in a case like this is
that it more accurately expresses the intention. The choice does not
involve whether to assign to a - that happens in both cases. The

Bingo. I hadn't realised that is *why* I like the "?" usage.

You immediately "at a glance" see that b is being assigned a value
whatever the result of a condition.
choice is between values to assign, so it is natural that the conditional
should be around the rhs only.

In a (common) case like

a = (a > max ? max : a)

the same argument suggests that you should use an if. Using ?:
conceals the fact that you really only want to modify a if it's too
big.

-- Richard

--
 
K

Keith Thompson

Richard said:
Bingo. I hadn't realised that is *why* I like the "?" usage.

You immediately "at a glance" see that b is being assigned a value
whatever the result of a condition.

Ok, good point.

[snip]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,069
Latest member
SimplyleanKetoReviews

Latest Threads

Top