-1

For example:

5*3 + 9*6

As far as I know, according to types of compilers in some 5*3 is evaluated first while in other compilers 9*6 is evaluated first.

Is there a function in C or technique that can check which is evaluated first?

mnille
  • 1,328
  • 4
  • 16
  • 20
Jin
  • 1,902
  • 3
  • 15
  • 26
  • For MSVC https://msdn.microsoft.com/en-us/library/2bxt6kc4.aspx – Jerry Jeremiah Jul 28 '16 at 05:07
  • I also found this: http://stackoverflow.com/questions/16530140/precedence-and-associativity-of-operators-in-c/16530162#16530162 and this http://stackoverflow.com/questions/7112282/order-of-evaluation-of-operands – Jerry Jeremiah Jul 28 '16 at 05:08
  • 3
    Given that there aren't side effects, what meaning does it have to "evaluate first" a part of the expression here? If the precedence rules are observed when combining the subexpressions, the order of evaluation of the terms isn't an observable phenomenon (unless stepping in the generated assembly with a debugger, but even there the situation is not so clear-cut). – Matteo Italia Jul 28 '16 at 05:09
  • Why do you need to check? I can understand wanting to fix the (otherwise unspecified) order in some situations (and you can do that by breaking the statement into three), but if don't need to fix it, why do you still need to check? – Thilo Jul 28 '16 at 05:13
  • 1
    ... Look at the generated code? – Carl Norum Jul 28 '16 at 05:18
  • @JerryJeremiah From the link you posted, the relevant part is `order of operations is not defined by the language`. – dxiv Jul 28 '16 at 05:25
  • 2
    @CarlNorum which, in this case, will be something like `mov eax, 69` – Matteo Italia Jul 28 '16 at 05:27

1 Answers1

0

Is there a function in C or technique that can check which is evaluated first?

You can define a function to multiply the numbers and add code to produce some output.

int multiply(int n1, int n2)
{
   printf("Computing %d*%d\n", n1, n2);
   return n1*n2;
}

and use the function to do the multiplication instead of using the multiplication operator.

multiply(5, 3) + multiply(9, 6);
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Ah, but how can you guarantee that the compiler won't inline the whole shebang and reorder the prints before (or after) the multiplications? – Matteo Italia Jul 28 '16 at 05:21
  • 1
    @MatteoItalia, that would be illegal because it would change the observable behavior of the program. – R Sahu Jul 28 '16 at 05:23
  • 1
    there's nothing observable in when arithmetic is performed, unless a write to a `volatile` variable is involved. Incidentally, in this precise case there's no need for an actual runtime multiplication, any optimizer worth anything will just put the result straight into the executable. – Matteo Italia Jul 28 '16 at 05:25
  • 1
    @MatteoItalia, compiler technology is not my expertise. Take my question with that in mind. How would a compiler optimize away the calls to `printf`? – R Sahu Jul 28 '16 at 05:28
  • who talked about optimizing away? What I'm saying is that the order of the prints bears no relation to the order of the multiplications, because the relative ordering of the print and of the actual calculation of the result is not observable behavior. In this specific case, a smart compiler will probably print in whatever order it prefers and, before, between or after, will put 69 in a register without actually performing any multiplication. – Matteo Italia Jul 28 '16 at 05:43
  • Order of printf is the observable behavior and optimizer will not modify it. – aragaer Jul 28 '16 at 05:48
  • 2
    @aragaer: the order of `printf` is observable behavior (albeit unspecified), the fact that they will be performed along with the multiplication is not, especially in a case like OP's, where everything is known at compile time, and the compiler can elide any actual calculation to be performed at runtime. After inlining, the compiler may do printf/mul/printf/mul/add, printf/printf/mul/mul/add, printf/fused mul-add/printf, printf/printf/mov of the result computed at compile time, mov/printf/printf, whatever. That is *not* observable behavior, *unless* you introduce a write to a `volatile` var. – Matteo Italia Jul 28 '16 at 05:52
  • https://godbolt.org/g/dWi7BB here it is; `straight` (just OP's expression) returns a precomputed value; `multiply` does what you would expect, but *is never actually invoked*, `using_multiply` inlines everything, does the two `printf`s (left to right, in this case) and at the end just returns the precomputed value. – Matteo Italia Jul 28 '16 at 07:01