?: as an lvalue

R

Rahul

Hi Everyone,

I have the following piece of code, and i expected an error, however
i don't get an error,

int main()
{
int aa=0,b=0;
1>0?aa:b = 10;
printf("value %d %d\n",aa,b);
return(0);
}

and output is value 0 0

Thanks in advance ! ! !
 
K

Kenny McCormack

Hi Everyone,

I have the following piece of code, and i expected an error, however
i don't get an error,

int main()
{
int aa=0,b=0;
1>0?aa:b = 10;
printf("value %d %d\n",aa,b);
return(0);
}

and output is value 0 0

Thanks in advance ! ! !

int main(void) is better
failure to include stdio.h
unnecessarily parenthesizing the return value
failure to indent the return statement properly
meaningless variable names
failure to capitalize "i" in text (e.g., "i don't get an error")
excessive use of exclamation points
improper capitalization of word "everyone"
use of tacky expression "Thanks in advance"
 
R

Richard Heathfield

Rahul said:
Hi Everyone,

I have the following piece of code, and i expected an error, however
i don't get an error,

int main()
{
int aa=0,b=0;
1>0?aa:b = 10;

This is a syntax error (which therefore requires the implementation to
diagnose it as such). The syntax of the conditional operator is:

conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression

which your code violates.
printf("value %d %d\n",aa,b);
return(0);
}

and output is value 0 0

Thanks in advance ! ! !

Turn up your warning level. Which implementation are you using?
 
F

Flash Gordon

Rahul wrote, On 30/03/08 12:05:
Hi Everyone,

I have the following piece of code, and i expected an error, however
i don't get an error,

In that case you need to tell your compiler to act as a C compiler
rather than as an extended-C-like-language compiler.
int main()
{
int aa=0,b=0;
1>0?aa:b = 10;

This is illegal and a C compiler is required to produce a diagnostic
(warning, error or whatever).
printf("value %d %d\n",aa,b);

Not related to your current problem, but you need to include stdio.h to
use printf.
return(0);
}

and output is value 0 0

If you want to do this then a legal way is as follows:
#include <stdio.h>

int main()
{
int aa=0,b=0;
*(1>0?&aa:&b) = 10;
printf("value %d %d\n",aa,b);
return(0);
}
 
B

Ben Bacarisse

Richard Heathfield said:
Rahul said:


This is a syntax error (which therefore requires the implementation to
diagnose it as such). The syntax of the conditional operator is:

conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression

which your code violates.

That is not really enough to show there is a syntax error. The
syntax for an assignment-expression

assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression

is more suggestive, but even then, the OP needs to know what might or
might not constitute a unary-expression. It is an interesting problem
to find the smallest set of grammar rules needed to show that any
given piece of C is a syntax error.
 
R

Rahul

Rahul said:




This is a syntax error (which therefore requires the implementation to
diagnose it as such). The syntax of the conditional operator is:

conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression

which your code violates.




Turn up your warning level. Which implementation are you using?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

I tried MS VC++ 8.0...
http://www.dinkumware.com/exam/default.aspx
 
P

Philip Potter

Rahul said:
Hi Everyone,

I have the following piece of code, and i expected an error, however
i don't get an error,

int main()
{
int aa=0,b=0;
1>0?aa:b = 10;
printf("value %d %d\n",aa,b);
return(0);
}

and output is value 0 0

Thanks in advance ! ! !

The result of the ?: operator is not an lvalue, and cannot be assigned to.

If you want to conditionally assign to one of two objects, it's probably
clearer to write it in full:

if (1>0)
aa = 0;
else
b = 10;

If you really want unreadable code, I suppose you could do this:
int *ip[2] = {&b,&aa};

*ip[1>0] = 10;

but if I worked with you I wouldn't thank you for it :)

Philip
 
B

Bartc

Philip Potter said:
Rahul wrote:
The result of the ?: operator is not an lvalue, and cannot be assigned to.

If you want to conditionally assign to one of two objects, it's probably
clearer to write it in full:

if (1>0)
aa = 0;
else
b = 10;

I think both these right-hand-sides should be 10.

Which is the problem, repeating a possibly complex expression.

But 'Flash' I think came up with simple mod of the OP's code which works and
keeps the code compact.
 
R

Richard Heathfield

Rahul said:
I tried MS VC++ 8.0...

I think the switches you'll need for Visual C are -W4 -Za

(-W4 turns the warning level up as far as it'll go - unless they've added
another level in the last few years - and -Za switches off Microsoft
extensions.)
 
P

Philip Potter

Bartc said:
I think both these right-hand-sides should be 10.

Which is the problem, repeating a possibly complex expression.

But 'Flash' I think came up with simple mod of the OP's code which works and
keeps the code compact.

Yes, I made a typo, but I'd still write it my way.

If you're worried about the complex expression being duplicated, use a
temporary:

int aa,b;
int tmp;
tmp = mycomplexexpr();
if (condition())
aa = tmp;
else
b = tmp;
 
A

Andrey Tarasevich

Rahul said:
I tried MS VC++ 8.0...

I tried the same compiler and got essentially the same error, saying that left
operand must be a lvalue.

If you tried it at this link, then most likely your code was compiled as C++. In
C++ it would be parsed as '1 > 0 ? aa : (b = 10)'. Additionally in C++ the
result of ?: can be lvalue. It is not surprise that you didn't get an error.
 
B

bert

Rahul said:
Hi Everyone,
 I have the following piece of code, and i expected an error, however
i don't get an error,
int main()
{
   int aa=0,b=0;
   1>0?aa:b = 10;
        printf("value %d %d\n",aa,b);
 return(0);
}
and output is value 0 0
Thanks in advance ! ! !

The result of the ?: operator is not an lvalue, and cannot be assigned to.

If you want to conditionally assign to one of two objects, it's probably
clearer to write it in full:

if (1>0)
    aa = 0;
else
    b = 10;

If you really want unreadable code, I suppose you could do this:
int *ip[2] = {&b,&aa};

*ip[1>0] = 10;

but if I worked with you I wouldn't thank you for it :)

For such requirements, I have written - and
been satisfied with - code of the style:

*(i > 0 ? &aa : &b) = <complicated expression>;
--
 
R

Richard

bert said:
Rahul said:
Hi Everyone,
 I have the following piece of code, and i expected an error, however
i don't get an error,
int main()
{
   int aa=0,b=0;
   1>0?aa:b = 10;
        printf("value %d %d\n",aa,b);
 return(0);
}
and output is value 0 0
Thanks in advance ! ! !

The result of the ?: operator is not an lvalue, and cannot be assigned to.

If you want to conditionally assign to one of two objects, it's probably
clearer to write it in full:

if (1>0)
    aa = 0;
else
    b = 10;

If you really want unreadable code, I suppose you could do this:
int *ip[2] = {&b,&aa};

*ip[1>0] = 10;

but if I worked with you I wouldn't thank you for it :)

For such requirements, I have written - and
been satisfied with - code of the style:

*(i > 0 ? &aa : &b) = <complicated expression>;

Well done - you'll make maintainers very happy in years to come.

What on earth is wrong with

v= complex expr;
if(i)
aa=v;
else
b=v;

Same number of characters give or take too .... Easy to see
flow/assignment in a debugger too. Very easy to read.
 
K

Kenny McCormack

Richard said:
Same number of characters give or take too .... Easy to see
flow/assignment in a debugger too. Very easy to read.

You know perfectly well that nobody here uses a debugger.
 
R

Richard Heathfield

Flash Gordon said:
Rahul wrote, On 30/03/08 12:05:

In that case you need to tell your compiler to act as a C compiler
rather than as an extended-C-like-language compiler.

The OP is using http://www.dinkumware.com/exam/default.aspx to test his
code. When I present that site with the following source:

#include <stdio.h>

int main(void)
{
int a = 0;
int b = 0;

1 > 0 ? a : b = 10;

printf("%d %d\n", a, b);

return 0;
}

and select the only C option I can find, which is the EDG C99 option, I get
no diagnostic messages whatsoever (unless you count "Code compiled
successfully!" as a diagnostic message).

Either this is a bug in EDG's compiler, or the rules changed in C99. I can
find no evidence of a rule change in C99.
 
A

Andrey Tarasevich

Richard said:
Either this is a bug in EDG's compiler, or the rules changed in C99. I can
find no evidence of a rule change in C99.

I tried compiling this with EDG/C99 option

void* v = 0;
int* p = v;

and it said that "a value of type "void *" cannot be used to initialize an
entity of type "int *"". I tried compiling this

int* p = (int[]) { 1, 2, 3 };

and it doesn't seem to know what it is. While this

class C {};

compiles successfully.

Obviously, EDG/C99 option actually stands for C++ compiler. What they mean by
C99 I don't know. In the output windows it says

Your code has been compiled with the EDG compiler using the Dinkum C99
library from the Dinkum Compleat Libraries package.

which probably means that C99 standard library used as C-portion of C++ standard
library.
 
R

Richard Heathfield

Andrey Tarasevich said:

[EDG C99] said that "a value of type "void *" cannot be used to
initialize an entity of type "int *"". I tried compiling this

int* p = (int[]) { 1, 2, 3 };

and it doesn't seem to know what it is. While this

class C {};

compiles successfully.

Obviously, EDG/C99 option actually stands for C++ compiler.

It would appear so. As another data point, it also diagnoses recursive
main:

"sourceFile.c", line 8: error:
function "main" may not be called or have its address taken
main(argc - 1, argv + 1);
^

1 error detected in the compilation of "sourceFile.c".

<snip>
 
B

bert

bert said:
Rahul wrote:
Hi Everyone,
 I have the following piece of code, and i expected an error, however
i don't get an error,
int main()
{
   int aa=0,b=0;
   1>0?aa:b = 10;
        printf("value %d %d\n",aa,b);
 return(0);
}
and output is value 0 0
Thanks in advance ! ! !
The result of the ?: operator is not an lvalue, and cannot be assigned to.
If you want to conditionally assign to one of two objects, it's probably
clearer to write it in full:
if (1>0)
    aa = 0;
else
    b = 10;
If you really want unreadable code, I suppose you could do this:
int *ip[2] = {&b,&aa};
*ip[1>0] = 10;
but if I worked with you I wouldn't thank you for it :)
For such requirements, I have written - and
been satisfied with - code of the style:
*(i > 0 ? &aa : &b) = <complicated expression>;

Well done - you'll make maintainers very happy in years to come.

I can't decide whether that's sarcasm from you, or real praise.
What on earth is wrong with

     v= complex expr;
     if(i)
        aa=v;
     else
        b=v;

Same number of characters give or take too .... Easy to see
flow/assignment in a debugger too. Very easy to read.- Hide quoted text -

The main thing "wrong" with your alternative
is the omission of a block structure.

{
int v = complicated expression;
if (i)
aa = v;
else
b = v;
}

would make it perfectly clear to a maintainer
in years to come that the only purpose of v
was to be assigned either to aa or to b.
--
 
R

Richard

bert said:
bert said:
Rahul wrote:
Hi Everyone,
 I have the following piece of code, and i expected an error, however
i don't get an error,
int main()
{
   int aa=0,b=0;
   1>0?aa:b = 10;
        printf("value %d %d\n",aa,b);
 return(0);
}
and output is value 0 0
Thanks in advance ! ! !
The result of the ?: operator is not an lvalue, and cannot be assigned to.
If you want to conditionally assign to one of two objects, it's probably
clearer to write it in full:
if (1>0)
    aa = 0;
else
    b = 10;
If you really want unreadable code, I suppose you could do this:
int *ip[2] = {&b,&aa};
*ip[1>0] = 10;
but if I worked with you I wouldn't thank you for it :)
For such requirements, I have written - and
been satisfied with - code of the style:
*(i > 0 ? &aa : &b) = <complicated expression>;

Well done - you'll make maintainers very happy in years to come.

I can't decide whether that's sarcasm from you, or real praise.
What on earth is wrong with

     v= complex expr;
     if(i)
        aa=v;
     else
        b=v;

Same number of characters give or take too .... Easy to see
flow/assignment in a debugger too. Very easy to read.- Hide quoted text -

The main thing "wrong" with your alternative
is the omission of a block structure.

There is no omission. It was concentrating on the core code.
{
int v = complicated expression;
if (i)
aa = v;
else
b = v;
}

would make it perfectly clear to a maintainer
in years to come that the only purpose of v
was to be assigned either to aa or to b.

That is another issue.
 
B

Bartc

bert said:
bert said:
Rahul wrote:
int main()
{
int aa=0,b=0;
1>0?aa:b = 10;
printf("value %d %d\n",aa,b);
return(0);
}
and output is value 0 0
The result of the ?: operator is not an lvalue, and cannot be
assigned to.
If you want to conditionally assign to one of two objects, it's
probably clearer to write it in full:
if (1>0)
aa = 0;
else
b = 10;
If you really want unreadable code, I suppose you could do this:
int *ip[2] = {&b,&aa};
*ip[1>0] = 10;
but if I worked with you I wouldn't thank you for it :)
For such requirements, I have written - and
been satisfied with - code of the style:
*(i > 0 ? &aa : &b) = <complicated expression>;

Well done - you'll make maintainers very happy in years to come.

I can't decide whether that's sarcasm from you, or real praise.

I don't think it was praise..
The main thing "wrong" with your alternative
is the omission of a block structure.

{
int v = complicated expression;
if (i)
aa = v;
else
b = v;
}

would make it perfectly clear to a maintainer
in years to come that the only purpose of v
was to be assigned either to aa or to b.

There was nothing much wrong with the original syntax:

a ? b : c = x;

(maybe better as (a ? b : c) = x;)

except that C doesn't allow it, and it's unfortunate that the legal format
is a little messy:

*(a ? &b ? &c) = x;

This is what the programmer wants to do, so why force him to create
unnecessary statements and to duplicate expressions, or declare unnecessary
temporary variables? All extra clutter.

Exactly why a?b:c can't appear like that on the left-hand-side of an
assignment is a bit of a mystery; after all a, a.b, a->b, a and so on can
all appear on the lhs without the programmer having to insert explicit
address-of operators.
 

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

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top