Parentheses and compiler optimzation

Discussion in 'C Programming' started by spasmous, Apr 10, 2008.

  1. spasmous

    spasmous Guest

    If a compiler see's the following statement

    c = (a+b)-b

    will it optimize it to c=a? I want to force the compiler to evaluate (a
    +b) first. Do the parentheses ensure an ANSI conforming compiler HAS
    to do that? If not, is there a way?
    spasmous, Apr 10, 2008
    #1
    1. Advertising

  2. spasmous

    Willem Guest

    spasmous wrote:
    ) If a compiler see's the following statement
    )
    ) c = (a+b)-b
    )
    ) will it optimize it to c=a?

    It could, yes.

    ) I want to force the compiler to evaluate (a+b) first.

    Why would you want to do that ?

    ) Do the parentheses ensure an ANSI conforming compiler HAS to do that?

    No, I don't think so. The as-if rule and such, you know.

    ) If not, is there a way?

    That depends. What *exactly* do you want to do ?
    The result will be the same no matter if the (a+b) is evaluated or not.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
    Willem, Apr 10, 2008
    #2
    1. Advertising

  3. In article <>,
    Willem <> wrote:
    >spasmous wrote:
    >) If a compiler see's the following statement


    >) c = (a+b)-b


    >) will it optimize it to c=a?


    >That depends. What *exactly* do you want to do ?
    >The result will be the same no matter if the (a+b) is evaluated or not.


    Think floating point. If a has a much smaller magnitude than b,
    then a+b would evaluate to b; b - b would then evaluate to 0, not a.
    Thus for floating point, optimizing (a+b)-b to simply a would give
    the "wrong" answer relative to floating point characteristics.

    --
    "I want to be remembered as the guy who gave his all whenever
    he was on the field." -- Walter Payton
    Walter Roberson, Apr 10, 2008
    #3
  4. spasmous <> writes:
    > If a compiler see's the following statement
    >
    > c = (a+b)-b
    >
    > will it optimize it to c=a?


    It's likely to to so, though there's no requirement to perform such an
    optimization.

    What types are a, b, and c? It might make a difference.


    > I want to force the compiler to evaluate (a
    > +b) first.


    Why? What problem are you really trying to solve? Ordinarily,
    replacing (a+b)-b by a will give you the same result.

    > Do the parentheses ensure an ANSI conforming compiler HAS
    > to do that?


    No, parentheses merely specify which operands are associated with
    which operators; they don't force any order of evaluation.

    > If not, is there a way?


    One obvious way is:

    tmp = a + b;
    c = tmp - b;

    but the compiler is still free to optimize it down to "c = a;".

    Judicious use of "volatile" might be a solution -- but again, without
    knowing the underlying problem, I hesitate to make suggestions.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Apr 10, 2008
    #4
  5. Morris Dovey wrote:
    >
    > spasmous wrote:
    > >
    > > If a compiler see's the following statement
    > >
    > > c = (a+b)-b
    > >
    > > will it optimize it to c=a? I want to force the compiler to evaluate (a
    > > +b) first. Do the parentheses ensure an ANSI conforming compiler HAS
    > > to do that? If not, is there a way?

    >
    > AFAICT, section 6.5[3] and footnote 71 assure that the
    > parenthesized expression (a+b) is evaluated first, then b is
    > subtracted from the result.


    AFAIK, unless b is volatile, no such requirement exists, just as
    there is no such requirement in

    c = ( printf("one") + printf("two") ) - printf("three");

    that the output be "onetwothree".

    And, AFAIK, even if b is volatile, there is no requirement that the
    one inside the parentheses is evaluated before the one outside.

    You could do something like

    c = a + b;
    c = c - b;

    but even then, a compiler could still optimize out the b's (unless
    it's volatile).

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
    Kenneth Brody, Apr 10, 2008
    #5
  6. In article <>,
    spasmous <> wrote:

    >If a compiler see's the following statement
    >
    >c = (a+b)-b
    >
    >will it optimize it to c=a? I want to force the compiler to evaluate (a
    >+b) first. Do the parentheses ensure an ANSI conforming compiler HAS
    >to do that?


    No.

    I seem to recall there was some dispute about this during the original
    C standardisation - you might be able to find it with Google.

    >If not, is there a way?


    Assigning the intermediate result to a volatile variable should
    ensure it.

    But you need to tell us what you are really trying to achieve.

    -- Richard
    --
    :wq
    Richard Tobin, Apr 10, 2008
    #6
  7. On Apr 10, 8:48 pm, spasmous <> wrote:
    > If a compiler see's the following statement
    >
    > c = (a+b)-b
    >
    > will it optimize it to c=a? I want to force the compiler to evaluate (a
    > +b) first. Do the parentheses ensure an ANSI conforming compiler HAS
    > to do that? If not, is there a way?


    The compiler will add a and b, then subtract b. Whether you use
    parentheses or not doesn't make any difference at all.

    However, there is the "as if" rule: The compiler is allowed to do
    _anything_ that is guaranteed to give exactly the same result. For
    example, if a and b are both of type unsigned int then it is
    guaranteed that (a + b) - b and a give the same result. On the other
    hand, if there _is_ a difference between (a + b) - b and a, then the
    compiler will _not_ produce a.
    christian.bau, Apr 10, 2008
    #7
  8. spasmous

    Guest

    Morris Dovey <> wrote:
    >
    > AFAICT, section 6.5[3] and footnote 71 assure that the
    > parenthesized expression (a+b) is evaluated first, then b is
    > subtracted from the result.


    In the abstract machine, but the as-if rule allows the compiler to
    optimize as long as it gets the same answer.

    -Larry Jones

    See if we can sell Mom and Dad into slavery for a star cruiser. -- Calvin
    , Apr 10, 2008
    #8
  9. Keith Thompson <> wrote:
    > spasmous <> writes:
    > > If a compiler see's the following statement
    > >
    > > c = (a+b)-b
    > >
    > > will it optimize it to c=a?

    >
    > It's likely to to so,


    Maybe, maybe not.

    > though there's no requirement to
    > perform such an optimization.


    There _is_ a requirement that no optimisation
    should change the behaviour from the virtual
    machine [if there is no unspecified or
    undefined behaviour.]

    Consider...

    int a = -1;
    unsigned b = 0;

    The expression (a + b) - b has neither the
    type nor value of a.

    Even if a and b have the same type there can
    be problems. See Walter's floating point
    example.

    --
    Peter
    Peter Nilsson, Apr 11, 2008
    #9
  10. spasmous

    Willem Guest

    Walter wrote:
    ) In article <>,
    ) Willem <> wrote:
    )>spasmous wrote:
    )>) If a compiler see's the following statement
    )
    )>) c = (a+b)-b
    )
    )>) will it optimize it to c=a?
    )
    )>That depends. What *exactly* do you want to do ?
    )>The result will be the same no matter if the (a+b) is evaluated or not.
    )
    ) Think floating point. If a has a much smaller magnitude than b,
    ) then a+b would evaluate to b; b - b would then evaluate to 0, not a.
    ) Thus for floating point, optimizing (a+b)-b to simply a would give
    ) the "wrong" answer relative to floating point characteristics.

    Oh, sorry. I assumed integer.

    If it's floating point, then no, the compiler is not allowed
    to optimize it away.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
    Willem, Apr 11, 2008
    #10
  11. Willem wrote:
    > Walter wrote:
    > ) In article <>,
    > ) Willem <> wrote:
    > )>spasmous wrote:
    > )>) If a compiler see's the following statement
    > )
    > )>) c = (a+b)-b
    > )
    > )>) will it optimize it to c=a?
    > )
    > )>That depends. What *exactly* do you want to do ?
    > )>The result will be the same no matter if the (a+b) is evaluated or not.
    > )
    > ) Think floating point. If a has a much smaller magnitude than b,
    > ) then a+b would evaluate to b; b - b would then evaluate to 0, not a.
    > ) Thus for floating point, optimizing (a+b)-b to simply a would give
    > ) the "wrong" answer relative to floating point characteristics.
    >
    > Oh, sorry. I assumed integer.


    The expression (-1 + 0u) - 0u has neither the type nor value of -1.

    --
    Peter
    Peter Nilsson, Apr 11, 2008
    #11
  12. Willem wrote:
    >
    > Walter wrote:
    > ) In article <>,
    > ) Willem <> wrote:
    > )>spasmous wrote:
    > )>) If a compiler see's the following statement
    > )
    > )>) c = (a+b)-b
    > )
    > )>) will it optimize it to c=a?
    > )
    > )>That depends. What *exactly* do you want to do ?
    > )>The result will be the same no matter if the (a+b) is evaluated or not.
    > )
    > ) Think floating point. If a has a much smaller magnitude than b,
    > ) then a+b would evaluate to b; b - b would then evaluate to 0, not a.
    > ) Thus for floating point, optimizing (a+b)-b to simply a would give
    > ) the "wrong" answer relative to floating point characteristics.
    >
    > Oh, sorry. I assumed integer.
    >
    > If it's floating point, then no, the compiler is not allowed
    > to optimize it away.


    I see that my compiler will optimize it away for int, but not for
    float. Where would one find this prohibition in the standard?

    Mathematically, "(a+b)-b" is the same as "a". Of course, in this
    case, there may be a loss of precision, but does the standard say
    that you must preserve loss of precision? Why doesn't the "as if"
    rule apply to floating point?

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
    Kenneth Brody, Apr 11, 2008
    #12
  13. In article <>,
    Kenneth Brody <> wrote:

    >Mathematically, "(a+b)-b" is the same as "a". Of course, in this
    >case, there may be a loss of precision, but does the standard say
    >that you must preserve loss of precision? Why doesn't the "as if"
    >rule apply to floating point?


    Your error is in your first line.

    Mathematically, "(a+b)-b" means whatever you want it to mean.
    You can -choose- to interpret it as a statement involving
    variables and operators, but there is no -inherent- meaning
    in using an operator named "+" or "-", so the operators can be
    given any interpretation. In logic, an "operator" is a function
    in the mathematical sense of "function", which is to say an arbitrary
    mapping from input tuples to output tuples. The mapping described
    by any particular "function" (and thus by any particular operator)
    need not make any -sense- -- it just *is*. Some mappings are amenable
    to being described more easily than just the exhaustive list of
    input and output tuples, but it is an error to -assume- that
    when you see operators "+" or "-" that those operators are definitely being
    used in the sense of a function mapping that has any kind of sensible
    or compact description.

    For example, it would be perfectly valid to use a mathematic model
    in which (a+b)-b was to be interpreted as NAND(XOR(a,b),b) -- which
    would, incidently, interpret "(a+b)-b" as mapping to "true" if a is false.

    Thus, when you read "(a+b)-b" in a C program, you should not be
    automatically interpreting this as algebraic addition and subtraction.
    Operations on signed integers need not obey standard algebraic rules
    in C (because a+b might overflow in signed integers, and the result
    of overflowing signed integers is not specified in C.) Operations on
    floating point numbers usually do not obey standard algebraic rules in C.
    Even with unsigned integers, do not expect standard algebraic rules:
    (a/b)*b is not a unless b is non-zero and a is an exact integral
    multiple of b.
    --
    'Roberson' is my family name; my given name is 'Walter'.
    Walter Roberson, Apr 11, 2008
    #13
  14. On Apr 11, 3:37 pm, Kenneth Brody <> wrote:
    > I see that my compiler will optimize it away for int, but not for
    > float.  Where would one find this prohibition in the standard?
    >
    > Mathematically, "(a+b)-b" is the same as "a".  Of course, in this
    > case, there may be a loss of precision, but does the standard say
    > that you must preserve loss of precision?  Why doesn't the "as if"
    > rule apply to floating point?


    The C Standard says that (a + b) - b means: Add a and b, subtract b
    from the result. Same for integer and floating point. The C Standard
    also says that the compiler is allowed to do absolutely anything it
    likes, but only as long as the result is exactly what the C Standard
    says. So the C Standard doesn't have to say "it's allowed for integer
    and not allowed for floating-point". Instead, it is up to the compiler
    writer to _prove_ that they produce exactly the same result.

    And: "Mathematically" doesn't count. Actually, when you say
    "mathematically" you mean "real numbers". Since the C Standard uses
    floating-point numbers and not real numbers, it is irrelevant how real
    numbers work.

    Now an example: How could the compiler optimise this?

    double f (int x) { double a = (double) x; double b = 1e300; return
    (a + b) - b; }

    (And no, it can't replace the return statement with "return a;" but
    with something very different!)
    christian.bau, Apr 11, 2008
    #14
  15. On Fri, 11 Apr 2008 14:35:06 -0700, christian.bau wrote:
    > Now an example: How could the compiler optimise this?
    >
    > double f (int x) { double a = (double) x; double b = 1e300; return
    > (a + b) - b; }
    >
    > (And no, it can't replace the return statement with "return a;" but with
    > something very different!)


    Yes, it can replace the return statement with "return a;", unless you
    specifically tell it it can't.

    6.5p8
    "A floating expression may be /contracted/, that is, evaluated as though
    it were an atomic operation, thereby omitting rounding errors implied by
    the source code and the expression evaluation method. The FP_CONTRACT
    pragma in <math.h> provides a way to disallow contracted expressions.
    Otherwise, whether and how expressions are contracted is implementation-
    defined."
    7.12.2p2
    "[...] The default state ("on" or "off") for the pragma is
    implementation-defined."
    Harald van Dijk, Apr 12, 2008
    #15
  16. spasmous

    Anonymous Guest

    On Thu, 10 Apr 2008 13:18:42 -0700, Keith Thompson wrote:

    > spasmous <> writes:
    >> If a compiler see's the following statement
    >>
    >> c = (a+b)-b
    >>
    >> will it optimize it to c=a?


    <snip>

    > One obvious way is:
    >
    > tmp = a + b;
    > c = tmp - b;
    >
    > but the compiler is still free to optimize it down to "c = a;".


    Chances are, as soon as the compiler finishes parsing the code and starts
    the first stage of compiling, this is already the form it's been reduced
    to. As far as optimizations go, this change is most likely a no-op unless
    tmp is volatile.

    > Judicious use of "volatile" might be a solution -- but again, without
    > knowing the underlying problem, I hesitate to make suggestions.


    Correct.
    Anonymous, Apr 13, 2008
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. chellappa

    Give some ideas for c Optimzation

    chellappa, Jul 7, 2005, in forum: C Programming
    Replies:
    18
    Views:
    527
    Chris Torek
    Jul 8, 2005
  2. rick

    AND and OR and parentheses

    rick, Aug 15, 2005, in forum: C Programming
    Replies:
    13
    Views:
    571
    Joe Wright
    Aug 20, 2005
  3. C parentheses, brackets and brace

    , Jun 15, 2007, in forum: C Programming
    Replies:
    8
    Views:
    863
    CBFalconer
    Jun 16, 2007
  4. jsnark

    parentheses and newlines

    jsnark, Feb 17, 2012, in forum: Ruby
    Replies:
    2
    Views:
    557
    Simon Krahnke
    Feb 18, 2012
  5. Addy
    Replies:
    2
    Views:
    104
    Anno Siegel
    Aug 26, 2003
Loading...

Share This Page