Re: c = foo(--a) + a; ?



Keith Thompson wrote:
Richard Heathfield <rjh@xxxxxxxxxxxxxxx> writes:
In <ha2o9i$a90$1@xxxxxxxxxxxxxxxxxxxxxxxxxx>, James Kuyper wrote:
[...]
In general, yes - but it took me only two seconds to think of a counter-example:

int x;

int foo(void)
{
printf("foo\n");
return 6;
}

int bar(void)
{
printf("bar\n");
return 42;
}

int baz(void)
{
x = foo() + bar();
printf("%d\n", x);
}

A compiler is allowed to notice that foo() and bar() return constants, and thus could emit code such as:

MOV x, 48
LEA R1, "foo\n" ;; or "bar\n", of course
CALL _printf
LEA R1, "bar\n" ;; or "foo\n", of course
CALL _printf
LEA R1, "%d\n"
MOV R2, x
CALL _printf

That is, it is allowed to assign to x before evaluating foo() and bar() (for their side effects).

I'm not convinced that that's correct. Function calls do involve
sequence points, and I suspect that modifying x before making the
calls would involve moving a side effect across a sequence point.

I haven't worked out the details. I've been saving your article for
the last day or two in anticipation of finding the time to do so.
Maybe somebody else can do the analysis?

If there were code in foo() or bar() or in their calls to
printf() that accessed x, the assignment would have to take place
after both foo() and bar() had returned. But if the compiler can
somehow know that no such accesses occur, it can reposition
the assignment as described.

It's probably pretty hard for the compiler to know that much
about a complicated function like printf(), but in principle the
jiggery-pokery appears possible. For a less intricate side-effect
than a printf() call -- say, assignments to globals foo_var and
bar_var -- the optimization seems more plausible.

--
Eric.Sosman@xxxxxxx
.



Relevant Pages

  • Re: StringBuilder Difficulties
    ... public foobar (int a, String b) { ... declares and initializes an immutable local if no mutable x is within scope, and assigns to the innermost in-scope mutable x otherwise. ... Definite assignment rules would still apply, more-or-less unchanged, ... being a definite assignment violation if no local x existed above "if foo" in that method body, a violation of finalness if a final x existed above "if foo" in the same block, and OK if a mutable x existed above "if foo" in the same scope and was definitely assigned to even if the ...
    (comp.lang.java.programmer)
  • Re: pid_t data type
    ... That's because the compiler generates machine code for the printf() ... pid_t foo; ... int, or cast the expression to an int. ...
    (comp.unix.programmer)
  • Re: c = foo(--a) + a; ?
    ... CALL _printf ... it is allowed to assign to x before evaluating foo() and ... bar(). ... int foo ...
    (comp.lang.c)
  • Re: c = foo(--a) + a; ?
    ... CALL _printf ... it is allowed to assign to x before evaluating foo() and ... bar(). ... int foo ...
    (comp.lang.c)
  • Re: c = foo(--a) + a; ?
    ... One might add a paragraph along the lines, "God did not will ... ... In general both of the operands of an assignment operator MUST be ... int foo ... CALL _printf ...
    (comp.lang.c)