Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > In how many ways should this fail?

Reply
Thread Tools

In how many ways should this fail?

 
 
Jens Gustedt
Guest
Posts: n/a
 
      01-30-2012
Am 01/30/2012 07:21 PM, schrieb BartC:
> "jacob navia" <(E-Mail Removed)> wrote in message
>> lcc-win diagnostics this as an error. A ternary operator construct
>> is not an lvalue.

>
> Strangely, your compiler was the only one of four where this worked
> completely as expected!


which were the other three?

Even without forcing them to a particular standard, for me gcc and
clang give the correct diagnostic and refuse to compile it.

Jens
 
Reply With Quote
 
 
 
 
BartC
Guest
Posts: n/a
 
      01-30-2012
"James Kuyper" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On 01/30/2012 01:16 PM, BartC wrote:


>> Only if the precedence of ?: is lower than for assignment. Used the other
>> way:

>
> The ?: operator can't be explained in terms of a simple precedence
> relative to other operators.
>
>> x = (a>b) ? a : b;
>>
>> You would expect the conditional expression to be evaluated first. Why
>> not
>> the same with the conditional on the left?

>
> Because I when gwowen wrote his comment, it sounded familiar, like
> something I already knew to be true, so I didn't bother to check. I just
> checked, and he was wrong, and I was therefore wrong to agree with his
> parse. The C grammar is:
>
> logical-OR-expression ? expression : conditional-expression


That doesn't make sense at all. The conditional-operator syntax is more
like:

expression1 ? expression2 : expression3

Parentheses are not usually needed because "the precedence of ?: is very
low, just above assignment" (from K&R). Why does the C grammar call
expression3 a conditional expression? Why is expression1 a
logical-OR-expression, when it can be anything that yields 0 or not 0?

Anyway, being just above assignment, your would expect a?b:c=d to evaluate
a?b:c just before being assigned d.

> In the following lines, I've inserted spaces to make corresponding parts
> line up with each other, but the alignment will not come out correctly
> unless viewed using a monospaced font:
>
> According to that grammar,
> a || b ? d , e : f ? g : h
> must be parsed as
> (a || b) ? (d , e) : (f ? g : h)
> but
> a ? b : c ? d , e : f = g
> must be parsed as
> (a ? b : (c ? (d , e) : f)) = g
> (that last parse results in a constraint violation, but it's not a
> syntax error).


Sorry, I don't get the above at all; what has a||b got to do with anything,
and why are there two lots of ?: on each line? The syntax shown on p. 51 of
K&R2 is pretty much what I wrote above.

> In all other contexts, the C grammar can be understood as giving || a
> higher precedence than =, giving both of them higher precedence than the
> comma operator. However, there's no way to insert ?: into that
> precedence hierarchy that explains both of the above parses.
>
> The C++ grammar is different, as I said, but I had the difference
> backwards:
> logical-or-expression ? expression : assignment-expression


I don't know what the C Standard document is on about; looking to the next
section, 6.5.16 Assignment, the conditional-expression occurs in the the
syntax for that too!

Actually I still don't know whether you agree with my interpretation of
a?b:c=d (as (a?b:c)=d rather than a?bc=d)) or not..

--
Bartc

 
Reply With Quote
 
 
 
 
BartC
Guest
Posts: n/a
 
      01-30-2012


"Jens Gustedt" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Am 01/30/2012 07:21 PM, schrieb BartC:
>> "jacob navia" <(E-Mail Removed)> wrote in message
>>> lcc-win diagnostics this as an error. A ternary operator construct
>>> is not an lvalue.

>>
>> Strangely, your compiler was the only one of four where this worked
>> completely as expected!

>
> which were the other three?


They were gcc 4.5.0, PellesC, and DigitalMars C.


--
Bartc


 
Reply With Quote
 
Jens Gustedt
Guest
Posts: n/a
 
      01-30-2012
Am 01/30/2012 08:32 PM, schrieb BartC:
> "Jens Gustedt" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> which were the other three?

>
> They were gcc 4.5.0, PellesC, and DigitalMars C.


hm strange, I have gcc 4.5.2 (on linux) and it gives me the correct
error report. Somebody in this thread mentioned that the extension to
allow ?: to be an lvalue has been remove with gcc 4.0

Jens
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      01-30-2012


"Jens Gustedt" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Am 01/30/2012 08:32 PM, schrieb BartC:
>> "Jens Gustedt" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed)...
>>> which were the other three?

>>
>> They were gcc 4.5.0, PellesC, and DigitalMars C.

>
> hm strange, I have gcc 4.5.2 (on linux) and it gives me the correct
> error report.


No, gcc was one of the three that didn't work, giving an error report.

When I said lccwin32 worked 'as expected', I meant that it allowed the
conditional operator on the left of an assignment and worked correctly...

--
Bartc

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-30-2012
"BartC" <(E-Mail Removed)> writes:
> "James Kuyper" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...

[...]
>> Because I when gwowen wrote his comment, it sounded familiar, like
>> something I already knew to be true, so I didn't bother to check. I just
>> checked, and he was wrong, and I was therefore wrong to agree with his
>> parse. The C grammar is:
>>
>> logical-OR-expression ? expression : conditional-expression

>
> That doesn't make sense at all. The conditional-operator syntax is more
> like:
>
> expression1 ? expression2 : expression3


It makes perfect sense if you understand how the C grammar defines
various kinds of expressions. "expression": is a particular
syntactic construct; "expression1", "expression2", and "expression3"
are not.

A "conditional-expression" isn't necessarily an expression with a
conditional operator. It's one of a number of grammatical constructs
used to build up the full definition of an "expression".

A "primary-expression" (C99 6.5.1) is defined as one of several
alternate forms (identifier, constant, string-literal, parenthesized
expression).

A "postfix-expression" (6.5.2) is either a "primary-expression"
or one of several other forms, most of which include another
"postfix-expression" (which can itself be a "primary-expression").

A "unary-expression" (6.5.3) is either a "postfix-expression"
or one of several other forms, most of which include another
"unary-expression" (which can itself be a "postfix-expression",
which can be a "primary-expression").

And so on, for about 17 levels.

The standard could have used a term like
"postfix-expression-or-some-more-primitive-expression", but that
would make the grammar very difficult to read. You just have to
understand that a postfix-expression doesn't mean "an expression
with a top-level postfix operator"; it's more general than that,
because the more general definition is more useful.

The point of having this definition:

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

rather than this one:

conditional-expression:
expression
expression ? expression : expression

is that it restricts the kind of expression that can be used as the
first or third operand. The first operand cannot have a conditional,
assignment, or comma operator at its top level; the third operand
cannot have an assignment or comma operator at its top level.

Of course you can add parentheses as needed to achieve the
same effect. An additive expression cannot be an operand of a
multiplication operator, but a primary expression can be, so you
can write (x + y) * z.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-30-2012
"BartC" <(E-Mail Removed)> writes:
> "Jens Gustedt" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> Am 01/30/2012 08:32 PM, schrieb BartC:
>>> "Jens Gustedt" <(E-Mail Removed)> wrote in message
>>> news:(E-Mail Removed)...
>>>> which were the other three?
>>>
>>> They were gcc 4.5.0, PellesC, and DigitalMars C.

>>
>> hm strange, I have gcc 4.5.2 (on linux) and it gives me the correct
>> error report.

>
> No, gcc was one of the three that didn't work, giving an error report.
>
> When I said lccwin32 worked 'as expected', I meant that it allowed the
> conditional operator on the left of an assignment and worked
> correctly...


And why would you expect that? The C standard explicitly states[*] that the conditional operator does not yield an lvalue, and
that an assignment requires an lvalue as its left operand.
[*] The statement is in a footnote, but the fact that the standard
doesn't say that it *does* yield an lvalue is sufficient.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      01-30-2012
On 01/30/2012 02:30 PM, BartC wrote:
> "James Kuyper" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> On 01/30/2012 01:16 PM, BartC wrote:

>
>>> Only if the precedence of ?: is lower than for assignment. Used the other
>>> way:

>>
>> The ?: operator can't be explained in terms of a simple precedence
>> relative to other operators.
>>
>>> x = (a>b) ? a : b;
>>>
>>> You would expect the conditional expression to be evaluated first. Why
>>> not
>>> the same with the conditional on the left?

>>
>> Because I when gwowen wrote his comment, it sounded familiar, like
>> something I already knew to be true, so I didn't bother to check. I just
>> checked, and he was wrong, and I was therefore wrong to agree with his
>> parse. The C grammar is:
>>
>> logical-OR-expression ? expression : conditional-expression

>
> That doesn't make sense at all. ...


It makes sense to me. More importantly, it's precisely what the C
standard specifies.

> ... The conditional-operator syntax is more
> like:
>
> expression1 ? expression2 : expression3


Not according to the C standard.

> Parentheses are not usually needed because "the precedence of ?: is very
> low, just above assignment" (from K&R). Why does the C grammar call
> expression3 a conditional expression? Why is expression1 a
> logical-OR-expression, when it can be anything that yields 0 or not 0?


expression1 and expression3 can't both be allowed to be conditional
expressions - that would make the parse of a ? b : c ? d : e ambiguous.
The standard made the choice that corresponds to parsing as a ? b : (c
? d : e) rather than (a ? b : c) ? d : e. I find this choice convenient
for writing a chain of ?: operators, which I presume is the reason why
they made that choice. The C99 rationale provides no insight into that
decision.
It also provides no insight about why they decided to disallow an
assignment expression as the third operand. As C++ has shown, there's
some use-cases for which that would be convenient.

> Anyway, being just above assignment, your would expect a?b:c=d to evaluate
> a?b:c just before being assigned d.


No, I wouldn't, because I know that in C, it's a constraint violation,
and in C++, it gets parsed differently.

>> In the following lines, I've inserted spaces to make corresponding parts
>> line up with each other, but the alignment will not come out correctly
>> unless viewed using a monospaced font:
>>
>> According to that grammar,
>> a || b ? d , e : f ? g : h
>> must be parsed as
>> (a || b) ? (d , e) : (f ? g : h)
>> but
>> a ? b : c ? d , e : f = g
>> must be parsed as
>> (a ? b : (c ? (d , e) : f)) = g
>> (that last parse results in a constraint violation, but it's not a
>> syntax error).

>
> Sorry, I don't get the above at all; what has a||b got to do with anything,
> and why are there two lots of ?: on each line? The syntax shown on p. 51 of
> K&R2 is pretty much what I wrote above.


A logical OR expression is the type of expression with the highest
"precedence" that can be the left operand of an ?: without using
parentheses; a conditional expression is the one with the lowest
"precedence" that requires parentheses to be used as the left operand of
another conditional expression.

A conditional expression is the type of expression with the highest
"precedence" that can be used without parentheses as the right operand
of a conditional expression. An assignment expression is the type of
expression that has the lowest precedence that requires use of
parentheses to be used as the right operand of a conditional operator.

Any expression can be used without parenthesis as the middle operand of
a conditional expression. A comma expression is the type that has the
lowest precedence.

I put my examples together using ||, two copies of ?:, =, and a comma
operator, in order to demonstrate all of those cases.

>> In all other contexts, the C grammar can be understood as giving || a
>> higher precedence than =, giving both of them higher precedence than the
>> comma operator. However, there's no way to insert ?: into that
>> precedence hierarchy that explains both of the above parses.
>>
>> The C++ grammar is different, as I said, but I had the difference
>> backwards:
>> logical-or-expression ? expression : assignment-expression

>
> I don't know what the C Standard document is on about; looking to the next
> section, 6.5.16 Assignment, the conditional-expression occurs in the the
> syntax for that too!


That's as it should be. The key thing that is peculiar about the
conditional operator is that the middle operand is completely
unambiguous: it must be bracketed by ? and :. As a result, any
expression is allowed for the middle operand. In all other respects, the
conditional operator has higher precedence than the assignment operator.

> Actually I still don't know whether you agree with my interpretation of
> a?b:c=d (as (a?b:c)=d rather than a?bc=d)) or not..


No, I do not. The C standard specifies a syntax that mandates parsing it
as (a?b:c)=d, and specifies a constraint that is necessarily violated by
that parse. If an implementation should choose to accept the program
after issuing the mandatory diagnostic, the behavior of any such program
is undefined.

The C++ standard specifies a syntax that mandates parsing it as a ? b :
(c=d). The expression (a?b:c)=d is not a constraint violation in C++,
but the parenthesis are not optional.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      01-30-2012
James Kuyper <(E-Mail Removed)> writes:

> On 01/30/2012 11:43 AM, BartC wrote:
>>
>>
>> "Devil with the China Blue Dress" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed)-september.org...
>>> In article <(E-Mail Removed)>,
>>> Anders Wegge Keller <(E-Mail Removed)> wrote:
>>>
>>>> At work, we got into a talk about weird C constructs. One of my
>>>> collegues volunteered this line:
>>>>
>>>> (a>b)?a:b = 42;
>>>
>>> *(a>b ? &a : &b) = 42;

>>
>> There's no reason why the original version shouldn't work. ...

>
> That depends upon what you mean by "work". The original expression is
> equivalent to
>
> b = 42;


No, it's a constraint violation.

> Which is unlikely to be what the author intended, and would be a pretty
> bizarre way of writing it if that was what he intended. Assuming that
> the parentheses needed to force the intended parse are inserted, there's
> still the problem that ((a>b)?a:b) isn't an lvalue.


No parentheses are needed. C parses the original as ((a>b)?a:b) = 42;

>> ... Doing as you
>> suggest is a bit like writing:
>>
>> *(&a) = 42;
>>
>> instead of a = 42. ...

>
> There's one key difference: *((a>b) ? &a : &b) = 42 is necessary in C,
> *(&a) = 42 is not.
>
>> ... It shouldn't be necessary and it's less readable.

>
> You're arguably correct about that. C++ allows the original expression
> to work as intended, even though C does not. This is because the C++
> grammar differs from the C grammar by not allowing the third operand to
> be an assignment expression,


You've got that the wrong way round. C++ permits the third operand to
be an assignment expression; C does not. The upshot is you do need
parentheses in C++ to get what the OP presumably wanted.

> and the C++ standard specifies that the
> result is an lvalue. They made the change because it makes some things
> involving C++ classes are more convenient; but the fact that it has been
> done is C++ means it could be done in C - that fact doesn't depend upon
> any C++-specific features.


--
Ben.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      01-30-2012
"BartC" <(E-Mail Removed)> writes:

> "James Kuyper" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> On 01/30/2012 01:16 PM, BartC wrote:

>
>>> Only if the precedence of ?: is lower than for assignment. Used the other
>>> way:

>>
>> The ?: operator can't be explained in terms of a simple precedence
>> relative to other operators.
>>
>>> x = (a>b) ? a : b;
>>>
>>> You would expect the conditional expression to be evaluated first. Why
>>> not
>>> the same with the conditional on the left?

>>
>> Because I when gwowen wrote his comment, it sounded familiar, like
>> something I already knew to be true, so I didn't bother to check. I just
>> checked, and he was wrong, and I was therefore wrong to agree with his
>> parse. The C grammar is:
>>
>> logical-OR-expression ? expression : conditional-expression

>
> That doesn't make sense at all. The conditional-operator syntax is more
> like:
>
> expression1 ? expression2 : expression3


That's not how syntax is expressed. You'd need productions for all of
expression1, expression2, and expression3. The C grammar correctly
encapsulates what is valid (syntactically) and what it not.

> Parentheses are not usually needed because "the precedence of ?: is very
> low, just above assignment" (from K&R). Why does the C grammar call
> expression3 a conditional expression? Why is expression1 a
> logical-OR-expression, when it can be anything that yields 0 or not 0?
>
> Anyway, being just above assignment, your would expect a?b:c=d to evaluate
> a?b:c just before being assigned d.


Forget about "before" and "after" -- precedence is about parsing, not
evaluation order. None the less, both you and K&R are correct: a?b:c=d
is parsed as (a?b:c)=d and results in a constraint violation. Even if C
permitted this, the parse does not reflect evaluation order. d could be
evaluated first or last -- it does not matter.

<snip>
>> The C++ grammar is different, as I said, but I had the difference
>> backwards:
>> logical-or-expression ? expression : assignment-expression

>
> I don't know what the C Standard document is on about; looking to the next
> section, 6.5.16 Assignment, the conditional-expression occurs in the the
> syntax for that too!


Yes. You'd have to read the notes about how the syntax notation works
first. Each line is a separate alternative, so the part you are
remarking on:

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

just says that an assignment expression can be a conditional expression
on its own. This is a common pattern. A typical operator expression
with precedence N looks like this:

operator-N-expression:
operator-N+1-expression
operator-N-expression OP operator-N+1-expression

A chain of such rules captures both the left associativity and
precedence rules we usually think in terms of. Swapping the order in
the second line would make OP right associative.

> Actually I still don't know whether you agree with my interpretation of
> a?b:c=d (as (a?b:c)=d rather than a?bc=d)) or not..


In C yes. What James writes here confirms it, but he did get it
backwards in another post. Unfortunately I replied to that post before
reading his correcting here.

--
Ben.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
How many ways we can call servlet from jsp? Garg Java 1 08-04-2006 05:59 AM
I need help in many ways (with Usenext) Nightcrawler2525 Computer Support 8 08-02-2006 11:19 PM
How many ways to watch Media Center recording on another TV? Lew DVD Video 0 07-03-2006 01:21 AM
how many ways to convert a integer to a string apple.davinci@gmail.com C Programming 12 03-10-2006 09:18 PM



Advertisments