Click on image to see enlargment

PC-lint/FlexeLint Output | Reference Manual Explanation | Home

            bug591.cpp

1    //lint -passes(2)   requires 2 passes
2    //lint -u           unit check out.
3    extern void other_calls_to_add(void);
4    enum meat { white, dark };
5    double cranberries = 0;
6    double turkey = 0;
7    extern double price_turkey, price_cran;
8
9    double add( double wt, meat kind )
10       {
11       double cfactor = kind == dark ? 1 : 2;
12       cranberries += cfactor * wt * .2;
13       return turkey += wt;
14       }
15
16   double total()
17       {
18       other_calls_to_add();
19       return price_turkey * add(.5,white) +
20              price_cran * cranberries;
21       }

Chef Alfredo, a better cook than programmer, wants to compute the cost of his Thanksgiving banquet using this (greatly simplified) program. In addition to all the other requirements he adds a half pound of white meat before returning the results. There is, however, a subtle flaw in his program. Can you find it?


bug591.cpp lint Output

--- Module:   bug591.cpp (C++)

/// Start of Pass 2 ///

--- Module:   bug591.cpp (C++)
                                   _
           price_cran * cranberries;
bug591.cpp  20  Warning 591: Variable 'cranberries' depends on the order of evaluation;
    it is modified through function 'add(double, enum meat)' via calls: add()

Reference Manual Explanation


591    Variable 'Symbol' depends on the order of evaluation; it is
       used/modified through function 'Symbol' via calls: String"  --
       The indicated variable (given by the first Symbol) was involved
       in an expression that contained a call of a function (given by
       the second Symbol) that would use or modify the variable.
       Further, the order of evaluation of the two is not determinable.
       For example:

                 extern int n;
                 void f() { n++; }
                 int g() { f(); return 1; }
                 int h() { return n + g(); }    // Warning 591

       The above code, on the second pass, will elicit the following
       warning:

                 Warning 591: Variable 'n' depends on the order of evaluation;
                 it is modified through function 'g(void)' via calls: g() => f()

       If the function g() is called and then n is added, you will obtain a
       different result than if n were first evaluated and then the call made.

       The programmer should generally rewrite these expressions so that
       the compiler is constrained to use the intended order.  For
       example if the programmer wanted to use the n prior to the call
       on g() it can alter h() to the following:

                 int h()
                     { int k = n; return k + g(); }

       This analysis requires two passes; the first pass builds the
       necessary call trees.


If you have comments or questions about this bug, please post them to our   Discussion Forum


Previous Bug - Bug #650 - October 2009

Use our Interactive Demo to Run FlexeLint on our Bugs of the Month

PC-lint/FlexeLint - Product Overview

Home | Contact | Order

PC-lint and FlexeLint are trademarks of Gimpel Software
Copyright 2009, Gimpel Software, All rights reserved.