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

About C and order of evaluation

10 views
Skip to first unread message

char...@yahoo.com

unread,
Oct 7, 2007, 10:29:24 PM10/7/07
to char...@gnet.gr
Hello, in the program below:

#include <stdio.h>

int main(void) {
int x = 1, y = 2, z;

z = x+++y;
return 0;
}

after executing, z has the value of 3, x is 2 and y is 2.

Can someone please explain me in detail why it is treated by the
compiler as (x++)+y and not for example as x+(++y) ?
What steps the compiler does to produce that result ?

Thanks for your time and sorry for my bad english

Charalampos Pournaris

Richard Heathfield

unread,
Oct 7, 2007, 10:39:36 PM10/7/07
to
char...@yahoo.com said:

<snip>



> z = x+++y;
> return 0;
> }
>
> after executing, z has the value of 3, x is 2 and y is 2.
>
> Can someone please explain me in detail why it is treated by the
> compiler as (x++)+y and not for example as x+(++y) ?

This is because of what is sometimes known as "maximum munch". The
preprocessor (which is responsible for converting the program into what
are called "preprocessing tokens" - "pp-tokens" for short) grabs the
largest token it can from the code stream. That is, it breaks off the
biggest piece it can chew.

Thus, z = x+++y; is parsed as

[z] [=] [++] [+] [y]

This is why x+++++y is not legal C, even though we can imagine how it might
be. We might think it's the same as x++ + ++y, but the preprocessor sees
it as [x] [++] [++] [+] [y] which is illegal.

Standard ref:

3.1 LEXICAL ELEMENTS

Semantics, para 2:

"If the input stream has been parsed into preprocessing tokens up to a
given character, the next preprocessing token is the longest sequence of
characters that could constitute a preprocessing token."

--
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

karthikbalaguru

unread,
Oct 8, 2007, 3:09:10 AM10/8/07
to
On Oct 8, 7:39 am, Richard Heathfield <r...@see.sig.invalid> wrote:

Interesting :):)

Karthik Balaguru

char...@yahoo.com

unread,
Oct 8, 2007, 6:29:26 AM10/8/07
to
On Oct 8, 5:39 am, Richard Heathfield <r...@see.sig.invalid> wrote:

Very interesting, thank you

char...@yahoo.com

unread,
Oct 8, 2007, 6:42:57 AM10/8/07
to
One more question,

The "maximum munch" on pp-tokens is always applied from left to right?
(The pp reads the stream in left->right order?)

Thanks

Richard Heathfield

unread,
Oct 8, 2007, 6:57:42 AM10/8/07
to
char...@yahoo.com said:

Yes.

Incidentally, I hope I didn't confuse you when I wrote:

Thus, z = x+++y; is parsed as

[z] [=] [++] [+] [y]

What I should have written is of course:

Thus, z = x+++y; is parsed as

[z] [=] [x] [++] [+] [y] [;]

Oops!

David Mathog

unread,
Oct 9, 2007, 12:13:52 PM10/9/07
to
Richard Heathfield wrote:

> Thus, z = x+++y; is parsed as
>

> [z] [=] [x] [++] [+] [y] [;]

The compiler may be happy with that code but I sure wouldn't be pleased
if it showed up in a program I had to maintain. It _looks_ like a typo,
and without analyzing the surrounding lines there's no way to tell if:

z = (x++)+y;

or

z = x+(++y);

was intended. This is another one of those instances where C
is a little too flexible (for my taste) about the syntax it will accept.
Sometimes it would be better if the compilers warned the
programmers to put in a few more spaces or parentheses so that the
meaning of the code would be unambiguous. That is unambiguous without
having to know arcane details about the how the compiler's parser
functioned.

Here's Hello World with all "extra" spaces and EOL's removed.
It's down to just 3 lines and two spaces: one between "int" and "main"
and one between "Hello" and "world". My news client wrapped this after
the second space but in the original it was only a 3 line program.

#include <stdlib.h>
#include <stdio.h>
int main(void){(void)fprintf(stdout,"Hello
world\n");(void)exit(EXIT_SUCCESS);}

This 3 line form is legal but it's also really hard to read. It would
be nice if gcc (for instance) had at least an optional -Whuman, to issue
warnings for difficult to read but otherwise legal constructs.


Regards,

David Mathog


santosh

unread,
Oct 9, 2007, 12:38:23 PM10/9/07
to
David Mathog wrote:

> Richard Heathfield wrote:
>
>> Thus, z = x+++y; is parsed as
>>
>> [z] [=] [x] [++] [+] [y] [;]
>
> The compiler may be happy with that code but I sure wouldn't be
> pleased
> if it showed up in a program I had to maintain. It _looks_ like a
> typo, and without analyzing the surrounding lines there's no way to
> tell if:
>
> z = (x++)+y;
>
> or
>
> z = x+(++y);
>
> was intended. This is another one of those instances where C
> is a little too flexible (for my taste) about the syntax it will
> accept.
> Sometimes it would be better if the compilers warned the
> programmers to put in a few more spaces or parentheses so that the
> meaning of the code would be unambiguous. That is unambiguous without
> having to know arcane details about the how the compiler's parser
> functioned.

It's not the compiler's job to teach the programming best coding
practices. No one prevents someone from writing clear, well formatted
source. Unfortunately too many C programmers have IOCCC ambitions.
Witness the recent thread started by Antoninus Twink complaining about
a piece of clear C code.

> Here's Hello World with all "extra" spaces and EOL's removed.
> It's down to just 3 lines and two spaces: one between "int" and "main"
> and one between "Hello" and "world". My news client wrapped this
> after the second space but in the original it was only a 3 line
> program.
>
> #include <stdlib.h>
> #include <stdio.h>
> int main(void){(void)fprintf(stdout,"Hello
> world\n");(void)exit(EXIT_SUCCESS);}
>
> This 3 line form is legal but it's also really hard to read. It would
> be nice if gcc (for instance) had at least an optional -Whuman, to
> issue warnings for difficult to read but otherwise legal constructs.

This is a subjective decision and I think, though I'm not sure, it will
be rather hard to implement. This is something that the programmer must
learn from good books and peers, not a compiler, IMHO.

Chris Dollin

unread,
Oct 10, 2007, 6:18:00 AM10/10/07
to
David Mathog wrote:

> Richard Heathfield wrote:
>
>> Thus, z = x+++y; is parsed as
>>
>> [z] [=] [x] [++] [+] [y] [;]
>
> The compiler may be happy with that code but I sure wouldn't be pleased
> if it showed up in a program I had to maintain.

"It's specified. But anyone who writes code like that should be
transmogrified into earthworms and fed to ducks."

I can't find the original, only echoes in sign-quotes, alas.

--
Chris "transmogrified ducks dollin" Dollin

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England

David Mathog

unread,
Oct 10, 2007, 12:12:42 PM10/10/07
to
santosh wrote:
> David Mathog wrote:

>> Sometimes it would be better if the compilers warned the
>> programmers to put in a few more spaces or parentheses so that the
>> meaning of the code would be unambiguous. That is unambiguous without
>> having to know arcane details about the how the compiler's parser
>> functioned.
>
> It's not the compiler's job to teach the programming best coding
> practices. No one prevents someone from writing clear, well formatted
> source. Unfortunately too many C programmers have IOCCC ambitions.
> Witness the recent thread started by Antoninus Twink complaining about
> a piece of clear C code.

Teach no, help with, yes. For the sake of argument, imagine that a
compiler had options like:

-Wfor_humans warn on difficult to read code
-Wstyle_fmt1 warn on source code not in specified style

Where the first would catch the "x+++y", and the second would pick up
on deviations from a specified coding style. These would be immensely
helpful, even if they have no effect whatsoever on the code generated.
Here is an example of the type of style variant I would love to be able
to flag.

if(some_condition)
do_something();

The lack of {} around the conditional code very often leads to errors
during code maintenance, and this can happen by accident when a stray
carriage return falls in the wrong place or an automatic line wrap
occurs unnoticed. Also, many projects have coding style standards, but
these are currently impossible to enforce using just the compiler. Some
projects want:


if(some_condition){
if(something_else){
}
}
else{
}

and another may demand:

if(some_condition) {
if(something_else) {
}
}
else {
}

It would be incredibly useful for me in these situations to be able to
throw a compiler switch to check for variation from these styles. The
compiler is clearly a good place to do this since it has to parse the
code thoroughly anyway, and could easily add a few more rules during
that parsing to pick up on things like indent levels, bracket spacing,
and split line if statements.

Regards,

David Mathog

Eric Sosman

unread,
Oct 10, 2007, 1:53:23 PM10/10/07
to
David Mathog wrote On 10/10/07 12:12,:

> santosh wrote:
>
>>David Mathog wrote:
>
>
>>> Sometimes it would be better if the compilers warned the
>>>programmers to put in a few more spaces or parentheses so that the
>>>meaning of the code would be unambiguous. That is unambiguous without
>>>having to know arcane details about the how the compiler's parser
>>>functioned.
>>
>>It's not the compiler's job to teach the programming best coding
>>practices. No one prevents someone from writing clear, well formatted
>>source. Unfortunately too many C programmers have IOCCC ambitions.
>>Witness the recent thread started by Antoninus Twink complaining about
>>a piece of clear C code.
>
>
> Teach no, help with, yes. For the sake of argument, imagine that a
> compiler had options like:
>
> -Wfor_humans warn on difficult to read code
> -Wstyle_fmt1 warn on source code not in specified style
>
> Where the first would catch the "x+++y", and the second would pick up
> on deviations from a specified coding style.

The great difficulty is in describing the "style" not
only in precise terms, but in computable terms. As an
exercise, try modifying gcc or another compiler to issue
warnings for departures from

PRE31-C. Never invoke an unsafe macro with
arguments containing assignment, increment,
decrement, or function call
-- CERT C Programming Language Secure Coding Standard
http://www.securecoding.cert.org/

(This rather rough work-in-progress was discussed on c.l.c.
in August of this year.) It's easy enough to get the compiler
to recognize the listed operations, but I think you may have
difficulty teaching it to distinguish "safe" from "unsafe"
macros.

> Here is an example of the type of style variant I would love to be able
> to flag.
>
> if(some_condition)
> do_something();
>
> The lack of {} around the conditional code very often leads to errors

> during code maintenance, [...]

Aside: This assertion is "very often" made, but is it
backed by measurement? I've been omitting braces from one-
line consequents of `if' and `for' and `while' for more
than three decades, and can't recall coming to grief as a
result.

> [...] Also, many projects have coding style standards, but

> these are currently impossible to enforce using just the compiler.

> [...] The


> compiler is clearly a good place to do this since it has to parse the
> code thoroughly anyway, and could easily add a few more rules during
> that parsing to pick up on things like indent levels, bracket spacing,
> and split line if statements.

First observation: It seems to me that the formatting of
the code is among the least important things to worry about.
Badly-formatted code is hard to read, yes, but if it's truly
terrible there's no shortage of code reformatters. If you're
happy with the rearrangements reformatters can make, what's
the point of requiring that they be made by humans instead?
Save human effort for the things machines *aren't* good at.

Second observation: I once shared your view that because
the compiler has to inspect the code anyhow, the compiler is
the logical "pinch point" at which to ensure good practice.
But fifteen or twenty years ago I changed my mind: the job
of the compiler is to translate the source code, not to
enforce some organization's standards. Different standards
apply in different organizations -- even in different projects
within the same organization -- so the compiler's suite of
standards would need to be localizable, which adds to the
complexity of the compiler. It's bad enough dealing with
optimizer bugs; do you also want to handle enforcer bugs?
How much time do you want to spend debugging the scripts
or whatever that describe the local style(s)?

Software engineering is a social activity (yes, even
for the so-called "loners"), and making sure that it is
done well and/or according to standards is a social issue.
Technology influences social issues, but is seldom in and
of itself a cure for social ills.

--
Eric....@sun.com

CBFalconer

unread,
Oct 10, 2007, 11:10:23 PM10/10/07
to
David Mathog wrote:
>
... snip ...

>
> Here's Hello World with all "extra" spaces and EOL's removed.
> It's down to just 3 lines and two spaces: one between "int" and
> "main" and one between "Hello" and "world". My news client
> wrapped this after the second space but in the original it was
> only a 3 line program.
>
> #include <stdlib.h>
> #include <stdio.h>
> int main(void){(void)fprintf(stdout,"Hello
> world\n");(void)exit(EXIT_SUCCESS);}
>
> This 3 line form is legal but it's also really hard to read. It
> would be nice if gcc (for instance) had at least an optional
> -Whuman, to issue warnings for difficult to read but otherwise
> legal constructs.

How about:

#include <stdio.h>
int main(void){puts("Hello World);return 0;}

and, if you really insist, you can (void)puts. Expanding to
minimum readability yields:

#include <stdio.h>
int main(void) {
puts("Hello World);
return 0;
}

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

CBFalconer

unread,
Oct 10, 2007, 11:24:53 PM10/10/07
to
Eric Sosman wrote:
> David Mathog wrote:
>
... snip ...
>
>> Here is an example of the type of style variant I would love to
>> be able to flag.
>>
>> if(some_condition)
>> do_something();
>>
>> The lack of {} around the conditional code very often leads to
>> errors during code maintenance, [...]
>
> Aside: This assertion is "very often" made, but is it backed by
> measurement? I've been omitting braces from one- line consequents
> of `if' and `for' and `while' for more than three decades, and
> can't recall coming to grief as a result.

My personal rule is that an if controlling a one liner can be
written as a one liner. I.e. in my world:

if (whatever()) something();
and
if (whatever()) {
foo();
something();
}

are both quite legitimate. Note I do not require 0 comparison in
the conditional.

CBFalconer

unread,
Oct 10, 2007, 11:16:32 PM10/10/07
to
David Mathog wrote:
>
... snip ...
>
> and another may demand:
>
> if(some_condition) {
> if(something_else) {
> }
> }
> else {
> }
>
> It would be incredibly useful for me in these situations to be able
> to throw a compiler switch to check for variation from these styles.
> The compiler is clearly a good place to do this since it has to
> parse the code thoroughly anyway, and could easily add a few more
> rules during that parsing to pick up on things like indent levels,
> bracket spacing, and split line if statements.

How about:

if (!some_condition) {
/* whatever */
}
else if (something_else) {
/* whatever else */
}

which I consider clearer.

David Mathog

unread,
Oct 11, 2007, 12:26:37 PM10/11/07
to
Eric Sosman wrote:
> David Mathog wrote On 10/10/07 12:12,:
>> Here is an example of the type of style variant I would love to be able
>> to flag.
>>
>> if(some_condition)
>> do_something();
>>
>> The lack of {} around the conditional code very often leads to errors
>> during code maintenance, [...]
>
> Aside: This assertion is "very often" made, but is it
> backed by measurement? I've been omitting braces from one-
> line consequents of `if' and `for' and `while' for more
> than three decades, and can't recall coming to grief as a
> result.

Measurement no, experience yes. I've seen bugs like this in other
people's code (not mine - I never uses this construct).
This one seems to be relatively common:

if(test)
do_1();
do_2();

I also recall seeing this once:

if(test)
do_1(); do_2();

In both cases resulting in subtle bugs where the code needed do_2() to
be conditional on test, whereas it actually ran unconditionally.
Beginner errors, yes, but once they are in the code, if the resulting
dysfunction isn't huge they can persist a long time.

So far I've not encountered this variant:

if(test)do(1); do_2();


Regards,

David Mathog

SM Ryan

unread,
Oct 19, 2007, 7:50:56 PM10/19/07
to
char...@yahoo.com wrote:

# z = x+++y;

It's not nice to fool Mother C.

'Doctor! Doctor! It hurts when I do this!'
'Then stop doing that.'

--
SM Ryan http://www.rawbw.com/~wyrmwif/
GERBILS
GERBILS
GERBILS

Charlie Gordon

unread,
Oct 21, 2007, 6:01:11 AM10/21/07
to
"CBFalconer" <cbfal...@yahoo.com> a écrit dans le message de news:
470D941F...@yahoo.com...

> David Mathog wrote:
>>
> ... snip ...
>>
>> Here's Hello World with all "extra" spaces and EOL's removed.
>> It's down to just 3 lines and two spaces: one between "int" and
>> "main" and one between "Hello" and "world". My news client
>> wrapped this after the second space but in the original it was
>> only a 3 line program.
>>
>> #include <stdlib.h>
>> #include <stdio.h>
>> int main(void){(void)fprintf(stdout,"Hello
>> world\n");(void)exit(EXIT_SUCCESS);}
>>
>> This 3 line form is legal but it's also really hard to read. It
>> would be nice if gcc (for instance) had at least an optional
>> -Whuman, to issue warnings for difficult to read but otherwise
>> legal constructs.
>
> How about:
>
> #include <stdio.h>
> int main(void){puts("Hello World);return 0;}
>
> and, if you really insist, you can (void)puts. Expanding to
> minimum readability yields:
>
> #include <stdio.h>
> int main(void) {
> puts("Hello World);
> return 0;
> }

Surely you meant this Mr Falconer:

#include <stdio.h>
int main(void) {
puts("Hello World");
return 0;
}

--
Chqrlie.


Orlando B. Salazar

unread,
Oct 21, 2007, 11:27:35 AM10/21/07
to

Are you determined to get from #8 to at least #2
in the "Top 20 posters by number of articles"
any way you can, or are you anal by nature?

Regards,
Orlando B. Salazar


Charlie Gordon

unread,
Oct 21, 2007, 4:57:36 PM10/21/07
to
"Orlando B. Salazar" <obsa...@regenzy.net> a écrit dans le message de
news: x6WdndV4vcQ6qoba...@giganews.com...

I guess anality rubs in on c.l.c, especially from reading posts by CBF and
RJH ;-)

--
Chqrlie.


0 new messages