Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
Per Westermark
05/28/12 14:51
Read: 747 times

Msg Score: +1
 +1 Informative
#187563 - Lazy evaluation demanded
Responding to: ???'s previous message
Justin Fontes said:
Secondly, I believe you are correct about the if statements with your compiler, but there is a slight hiccup. There is no way a break can be used after an if statement. A break only applies to a loop.

The code Erik mentioned is not correct.

A loop or a switch statement is needed for break.

But correct or not depends on if the posted sample is considered complete code (which it obviously isn't - the variables aren't declared either) or just an example that break can sometimes control program flow in more ways than exiting a multi-iteration loop.

And the reason I didn't post assembler instructions for a solution with break, was that for a single standalone if statement, I didn't want to introduce a dummy do { } while (false) just to support "break". But there are situations where I do write such code - it's a kind of poor mans exceptions when writing C code. So a large number of error conditions can jump out of the main execution chain and get handled directly after the while ends - while the "all-is-well" part returns just before the end of the "loop".

Another thing is that when writing #define code, it's common to have dummy "do { ... } while (0)" constructs just to make sure that the code looks like a single statement with a demand for a ';' after. So a #define EVAL(x) can (and must) be used as "EVAL(10);" in the source code. And hence guarantee that the code is safe in any combination of if/else. And any smart compiler will recognize that such a loop will always run one (1) time and don't need to result in any real code. It's just syntax glue.

However, under the guise that the compiler is not hitting the speed limit of the standard C Optimization ruling and that it is under optimized, the true logic would be to guarantee that all values are tested and that's a strict logic.

But the language standard specifically demands early-out for logic expressions. It's not optional.

You must be able to test for division-by-zero and perform the division in the same expression without the division-by-zero being computed.

And you must be able to use sub-expressions with side effects (like function calls that performs something) without extra function calls being made just for complete evaluation.

So it isn't just an issue of speed, but that you in some situations get different results if you do, or do not, compute the complete expression or only as much as is needed to resolve the expression to true or false.

An expression with multiple || will (and must) end evaluation on first true.
An expression with multiple && will (and must) end evaluation on first false.

I am unsure how the C Standard came up with rules to say that certain logic is "the same" and has no impact upon programming because as my analogy showed earlier, fractions with totally different numerators and denominators can have a huge impact on results and cannot be considered to be the same in the case of statistics. So, I guess there are some cases in C, but that seems a little un-trustworthy.

The C standard don't care about "the same". The constructs have defined rules for what they must do. And what they must not do. The optimization steps (not demanded by any standard) of better compilers will then look at code and see how the required tasks can be rewritten into lighter sequences of instructions. So a C compiler can always generate different code for "while (true)" and "for (;;)" but there isn't an advantage to do so. They solve the same problem, and if there is an optimum sequence of processor instructions that optimum could be used for both C constructs. In the same way, compilers normally perform much of the for loop evaluations last - but the source construct implies that the break test is done before entering the inner block. So many compilers starts the for loop with a jump to the end of the block, for performing the comparison (but jumping just after the code that performs any post-increment/decrement). In some situations, the compiler can figure out that this jump isn't needed - that the for loop is guaranteed to need at least one iteration, in which case it can perform the body code once before performing the first comparison. So better compilers can skip this jump for a (for i = 0; i < 100; i++) loop.

List of 33 messages in thread
Where can one learn Intermediate C techniques for 8051      David Good      05/22/12 17:42      
   on the right track        Maarten Brock      05/23/12 06:11      
      one more thing      Erik Malund      05/23/12 07:15      
         Not uncommon bid bad coding standards to comply with      Per Westermark      05/23/12 08:14      
         Not afraid of globals, but...      David Good      05/23/12 10:07      
   More keil optimizer interesting tidbits      David Good      05/24/12 16:24      
      optimization      Maarten Brock      05/25/12 05:35      
      nothing gained, nothing lost      Erik Malund      05/25/12 07:53      
         I don't      Per Westermark      05/25/12 07:58      
            you can do both      Erik Malund      05/25/12 09:44      
               That is not helping the compiler      Justin Fontes      05/25/12 16:31      
                  exact same      Maarten Brock      05/26/12 03:36      
                     Technically, they are not the same      Justin Fontes      05/26/12 11:17      
                        Hmmm...      Andy Neil      05/26/12 23:46      
                        C don't do full evaluation of logical expressions      Per Westermark      05/28/12 06:33      
                           In discrete mathematics proving one is not a proof      Justin Fontes      05/28/12 14:02      
                              Lazy evaluation demanded        Per Westermark      05/28/12 14:51      
                                 I have learned something new because of this      Justin Fontes      05/28/12 17:54      
                                    me too      Andy Peters      06/01/12 11:43      
                                       Very Important      Michael Karas      06/01/12 14:30      
                              Breaks.      Michael Karas      05/28/12 17:57      
                                 Compile the code      Justin Fontes      05/28/12 18:28      
                                    To be more exact      Justin Fontes      05/28/12 19:11      
                                       Stop It!!        Michael Karas      05/28/12 22:01      
                                          That is exactly what I intended      Justin Fontes      05/29/12 10:16      
                                             Switch Break.      Michael Karas      05/29/12 22:04      
               obfusciating code to help the compiler is a VERY bad idea      Andy Neil      05/27/12 07:13      
                  the source of this      Erik Malund      05/27/12 07:17      
   Where can one learn Intermediate C techniques for 8051      Andy Neil      05/26/12 23:56      
   Getting the least out of your compiler        Andy Neil      05/27/12 07:25      
      Maybe IAR should follow their own advice?      Christoph Franck      05/30/12 02:05      
         provided the case ...      Maarten Brock      05/30/12 06:29      
            Compilers not knowing the target chip.      Christoph Franck      05/31/12 03:19      

Back to Subject List