Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

a macro that uses ( ? : ) conditional as an lvalue

5 views
Skip to first unread message

Guy Rosman

unread,
Mar 25, 2002, 12:40:59 AM3/25/02
to
Hi
I tried to compile this code on several compilers (mostly gcc's and vc 6)
and it doesn't work, and yet one would reason the following macro should be
replaces by either "a" or "b", both valid lvalues:

#include <stdio.h>

#define SMAX(x,y) ( (x<y) ? x : y)
int main()
{
int a,b;
a=5;
b=3;
SMAX(a,b)=1; /* compilers say 'not an lvalue' */
return 0;
}

I've also seen stroustrup use something similar in his book (the c++ prog.
lang., 3rd ed., sec. 7.8, a macro called MIN), so if c++ has a different say
about it, I'd also like to know, also it's a C newsgroup.
pls also send a copy to my mail given above,
Thanks for anyone's trouble,
Guy Rosman
--
comp.lang.c.moderated - moderation address: cl...@plethora.net

Svante

unread,
Mar 25, 2002, 2:11:35 PM3/25/02
to
"Guy Rosman" <ken...@nonstop.co.il> wrote in message news:clcm-2002...@plethora.net...

> Hi
> I tried to compile this code on several compilers (mostly gcc's and vc 6)
> and it doesn't work, and yet one would reason the following macro should be
> replaces by either "a" or "b", both valid lvalues:
>
> #include <stdio.h>
>
> #define SMAX(x,y) ( (x<y) ? x : y)
> int main()

In C it's int main(void)

> {
> int a,b;
> a=5;
> b=3;
> SMAX(a,b)=1; /* compilers say 'not an lvalue' */

Exactly. In C, the conditional operator never returns an lvalue.
This simply does not work in C. Listen to your compiler, and
when in dobut, check your documentation.

> return 0;
> }
>
> I've also seen stroustrup use something similar in his book (the c++ prog.
> lang., 3rd ed., sec. 7.8, a macro called MIN), so if c++ has a different say
> about it, I'd also like to know, also it's a C newsgroup.

<offtopic>
Yes, C++ has a different way about it. In C++, if the second and third operarands
are lvalues, and are of the same type, the result is also an lvalue of that
type. It's still not a very good way of doing it. In C++, if you want to do this,
I would definitely not use a macro.
</offtopic>

(snip)

--
/Svante

http://axcrypt.sourceforge.net
Free AES Point'n'Click File Encryption for Windows 9x/ME/2K/XP

Joona I Palaste

unread,
Mar 25, 2002, 2:11:39 PM3/25/02
to
Guy Rosman <ken...@nonstop.co.il> scribbled the following
on comp.lang.c:

> #include <stdio.h>

This is simple. C++ is not C. In C++, ((x<y)?x:y) is an lvalue. In C,
it is not.

--
/-- Joona Palaste (pal...@cc.helsinki.fi) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"When a man talks dirty to a woman, that's sexual harassment. When a woman talks
dirty to a man, that's 14.99 per minute + local telephone charges!"
- Ruben Stiller

Blair P. Houghton

unread,
Mar 25, 2002, 2:11:41 PM3/25/02
to comp-lang-...@moderators.isc.org

The ?: expression doesn't lexically replace itself with the selected
identifier. It computes the value of the conditional expression at
runtime and returns the value selected. That is a value, not an l-value.

Now, you might do it with this, though I haven't tested it, so
you could try it and tell me if it goes okay:

#define SMAX(x,y) *( (x<y) ? &x : &y )

I get the feeling I might be running afoul of the allowed
result types for the conditional operator.

--Blair
"I'll be lucky if this post
gets to the moderator..."

Jack Klein

unread,
Mar 25, 2002, 2:11:44 PM3/25/02
to
On 25 Mar 2002 05:40:59 GMT, "Guy Rosman" <ken...@nonstop.co.il>
wrote in comp.lang.c:

> Hi
> I tried to compile this code on several compilers (mostly gcc's and vc 6)
> and it doesn't work, and yet one would reason the following macro should be
> replaces by either "a" or "b", both valid lvalues:
>
> #include <stdio.h>
>
> #define SMAX(x,y) ( (x<y) ? x : y)

The ternary operator in C evaluates one of two expressions and
produces its value.

> int main()
> {
> int a,b;
> a=5;
> b=3;
> SMAX(a,b)=1; /* compilers say 'not an lvalue' */

Given the assignments to a and b above, the SMAX macro produces the
value 3. Three is not an lvalue, that is a variable object into which
you can store a value.

In C this code is and always has been illegal.

> return 0;
> }
>
> I've also seen stroustrup use something similar in his book (the c++ prog.
> lang., 3rd ed., sec. 7.8, a macro called MIN), so if c++ has a different say
> about it, I'd also like to know, also it's a C newsgroup.
> pls also send a copy to my mail given above,
> Thanks for anyone's trouble,
> Guy Rosman

The notion that C++ is a superset of C is just plain nonsense,
Stroustrup himself says so. If this code is acceptable in C++, it is
just one more case where the designers of C++ decided to change the
rules, but actually whether or not it is acceptable in C++ is not an
issue for C newsgroups.

The C language existed long before C++ was based on modifications and
additions to it. Whether this is legal C++ code, and why the
designers of C++ decided to make this change, is a topic for groups
like comp.lang.c++ and comp.lang.c++.moderated. They are the ones who
decided to treat something differently than C did, not the other way
around.

If you want this macro to work in C code, you need to make two
changes:

#define SMAX(x,y) ( (x<y) ? &x : &y)

....and invoke it like this:

*SMAX(a, b) = 1;

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

David Neary

unread,
Mar 25, 2002, 2:11:53 PM3/25/02
to
On 25 Mar 2002 05:40:59 GMT, Guy Rosman said:
> Hi
> I tried to compile this code on several compilers (mostly gcc's and vc 6)
> and it doesn't work, and yet one would reason the following macro should be
> replaces by either "a" or "b", both valid lvalues:

No - your mistake is here. SMAX(a,b) gets replaced by
((a>b)?a:b)
(by the way, you should consider changing that to
(((a)>(b))?(a):(b))
to avoid any complex-expression problems)

> SMAX(a,b)=1; /* compilers say 'not an lvalue' */

((a>b)?a:b)=1; /* Isn't valid C /*
/* There's no better way to do this than
* (a>b)?a=1:b=1;
* as far as I can tell
*/

Cheers,
Dave.

--
David Neary,
E-Mail: bolsh at gimp dot org

Hans-Bernhard Broeker

unread,
Mar 25, 2002, 2:12:35 PM3/25/02
to
In comp.lang.c.moderated Guy Rosman <ken...@nonstop.co.il> wrote:
> Hi
> I tried to compile this code on several compilers (mostly gcc's and vc 6)
> and it doesn't work, and yet one would reason the following macro should be
> replaces by either "a" or "b", both valid lvalues:

No, it shouldn't. The macro will be replaced by an expression. That
expression then evaluates to one of two possible values. But, and
that's the catch: the result of a ( ? : ) expression is not an lavalue
itself, in C. It's the value of one of the two operands after the ?,
not that operand itself.

> SMAX(a,b)=1; /* compilers say 'not an lvalue' */

And it's right about that.

> I've also seen stroustrup use something similar in his book (the c++
> prog. lang., 3rd ed., sec. 7.8, a macro called MIN), so if c++ has
> a different say about it, I'd also like to know, also it's a C
> newsgroup.

IIRC, this is indeed one of the actual differences in semantics between
C++ and C.

--
Hans-Bernhard Broeker (bro...@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.

Francis Glassborow

unread,
Mar 25, 2002, 2:12:57 PM3/25/02
to
In article <clcm-2002...@plethora.net>, Guy Rosman
<ken...@nonstop.co.il> writes

>Hi
>I tried to compile this code on several compilers (mostly gcc's and vc 6)
>and it doesn't work, and yet one would reason the following macro should be
>replaces by either "a" or "b", both valid lvalues:
>
>#include <stdio.h>
>
>#define SMAX(x,y) ( (x<y) ? x : y)
>int main()
>{
>int a,b;
>a=5;
>b=3;
>SMAX(a,b)=1; /* compilers say 'not an lvalue' */
>return 0;
>}
>
>I've also seen stroustrup use something similar in his book (the c++ prog.
>lang., 3rd ed., sec. 7.8, a macro called MIN), so if c++ has a different say
>about it, I'd also like to know, also it's a C newsgroup.
>pls also send a copy to my mail given above,
why? what is wrong with reading the answer where you asked it?

>Thanks for anyone's trouble,

And your compilers are entirely correct. In C the conditional operator
returns a pure value (aka rvalue) while in C++ it can return a reference
(which is an lvalue) In practice sane C++ programmers avoid using this.
However you do not need to know that as you are writing C where your
code will not work.


--
Francis Glassborow
Check out the ACCU Spring Conference 2002
4 Days, 4 tracks, 4+ languages, World class speakers
For details see: http://www.accu.org/events/public/accu0204.htm

Eric Amick

unread,
Mar 25, 2002, 2:13:12 PM3/25/02
to
"Guy Rosman" <ken...@nonstop.co.il> wrote in message
news:clcm-2002...@plethora.net...

> Hi
> I tried to compile this code on several compilers (mostly gcc's and vc
6)
> and it doesn't work, and yet one would reason the following macro
should be
> replaces by either "a" or "b", both valid lvalues:
>
> #include <stdio.h>
>
> #define SMAX(x,y) ( (x<y) ? x : y)
> int main()
> {
> int a,b;
> a=5;
> b=3;
> SMAX(a,b)=1; /* compilers say 'not an lvalue' */
> return 0;
> }
>
> I've also seen stroustrup use something similar in his book (the c++
prog.
> lang., 3rd ed., sec. 7.8, a macro called MIN), so if c++ has a
different say
> about it, I'd also like to know, also it's a C newsgroup.
> pls also send a copy to my mail given above,

The ?: operator can't produce an lvalue in C, unlike in C++. And if you
go to the trouble of posting here, you can bother to read the reply
here.

--
Eric Amick
Columbia, MD
eric-...@comcast.net

jacob de bruin

unread,
Mar 25, 2002, 2:13:23 PM3/25/02
to
hi Guy,

at least one of your compilers (vc6) will accept a ?: macro,
but only if the result is an address (e.g. a pointer to an int).

---Sample source ---
#include <stdio.h>
#define PMAX(x,y) ((x>y)?&x:&y)
#define SMAX(x,y) *(PMAX(x,y))
int main(void)
{
int a=5,b=3;
SMAX(a,b)=1;
printf( "a=%d, b=%d\n", a, b );
SMAX(a,b)=1;
printf( "a=%d, b=%d\n", a, b );
return 0;
}
---screen output---
a=1, b=3
a=1, b=1
---
so ...
...it works, however I cannot complete my verdict on why this is valid C.
Maybe some of the C Guru Judges out there can ...

jacob


"Guy Rosman" <ken...@nonstop.co.il> wrote in message
news:clcm-2002...@plethora.net...

Jos A. Horsmeier

unread,
Mar 25, 2002, 11:48:08 PM3/25/02
to
"Guy Rosman" <ken...@nonstop.co.il> wrote in message
news:clcm-2002...@plethora.net...
> I tried to compile this code on several compilers (mostly gcc's and vc 6)
> and it doesn't work, and yet one would reason the following macro should
be
> replaces by either "a" or "b", both valid lvalues:
>
> #include <stdio.h>
>
> #define SMAX(x,y) ( (x<y) ? x : y)
> int main()
> {
> int a,b;
> a=5;
> b=3;
> SMAX(a,b)=1; /* compilers say 'not an lvalue' */
> return 0;
> }

The standard states: 'a conditional expression does not yield an lvalue', so
gcc and vc6 are right here. But there's a little trick that may help you
out:

#define SMAX(x, y) (*(((x) < (y)) ? &(x) : &(y)))

/* ... */

SMAX(a, b)= 1;

kind regards,

Jos aka j...@gen.nl

Andy Isaacson

unread,
Mar 25, 2002, 11:48:10 PM3/25/02
to
In article <clcm-2002...@plethora.net>,

Guy Rosman <ken...@nonstop.co.il> wrote:
>Hi
>I tried to compile this code on several compilers (mostly gcc's and vc 6)
>and it doesn't work, and yet one would reason the following macro should be
>replaces by either "a" or "b", both valid lvalues:
>
>#define SMAX(x,y) ( (x<y) ? x : y)
[snip]

>SMAX(a,b)=1; /* compilers say 'not an lvalue' */

The ?: operator does not generate an lvalue. You could do something like

#define ASMAX(x,y) *( (x<y) ? &x : &y)
ASMAX(a,b) = 1;

>I've also seen stroustrup use something similar in his book (the c++ prog.
>lang., 3rd ed., sec. 7.8, a macro called MIN), so if c++ has a different say
>about it, I'd also like to know, also it's a C newsgroup.

C++ is a different language from C, and the rules are different. Some
things that are not valid C programs are valid C++ programs. I don't
know the details of C++ well enough to comment further.

>pls also send a copy to my mail given above,

Post here, read here. Look at google if your news server drops messages.

-andy

butterbrain

unread,
Mar 25, 2002, 11:48:12 PM3/25/02
to
3 = 1;

C doesn't let you change the value of 3.

Kenneth Brody

unread,
Mar 25, 2002, 11:48:14 PM3/25/02
to
Guy Rosman wrote:
[...]

> #define SMAX(x,y) ( (x<y) ? x : y)
[...]

> SMAX(a,b)=1; /* compilers say 'not an lvalue' */
[...]

Well, as the compiler says, SMAX() does not result in an lvalue.

The following works on my compiler here. I don't know for certain if
it is guaranteed to work, but I'm sure others here can comment on that.

#define SMAX(x,y) *( (x<y) ? &x : &y )

On a side note, shouldn't this be "x>y" to get the max value?

--

+---------+----------------------------------+-----------------------------+
| Kenneth | kenbrody at spamcop.net | "The opinions expressed |
| J. | | herein are not necessarily |
| Brody | http://www.hvcomputer.com | those of fP Technologies." |
+---------+----------------------------------+-----------------------------+
GCS (ver 3.12) d- s+++: a C++$(+++) ULAVHSC^++++$ P+>+++ L+(++) E-(---)
W++ N+ o+ K(---) w@ M@ V- PS++(+) PE@ Y+ PGP-(+) t+ R@ tv+() b+
DI+(++++) D---() G e* h---- r+++ y?

Erik Max Francis

unread,
Mar 25, 2002, 11:48:18 PM3/25/02
to
Svante wrote:

> > #define SMAX(x,y) ( (x<y) ? x : y)
> > int main()
>
> In C it's int main(void)

In a declaration, that's true. But in a definition, int main() is
perfectly valid. An empty function parameter list is only ambiguous in
a declaration, not a definition. The usage here was a definition, so it
was perfectly valid.

--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/ \ Laws are silent in time of war.
\__/ Cicero
Esperanto reference / http://www.alcyone.com/max/lang/esperanto/
An Esperanto reference for English speakers.

Bjoern Pedersen Tel. 14707

unread,
Mar 26, 2002, 12:30:28 PM3/26/02
to
"Guy Rosman" <ken...@nonstop.co.il> writes:
>
> #include <stdio.h>
>
> #define SMAX(x,y) ( (x<y) ? x : y)
And beware, this macro will evaluate either x or y twice, so something
like

SMAX(a++,b)

may not give the results you would expect:

expansion yields:

(a++<b) ? a++: b

so if a < b+1 , a will get incremented twice.

Björn

--
Bjoern Pedersen Lichtenbergstr.1
Technische Universitaet Muenchen D-85747 Garching
ZBE Instrumentierung FRM-II
Tel. + 49 89 289-14707 Fax -14666

0 new messages