Click on image to see enlargment

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

            bug456.cpp

1    //lint -sem( lock, thread_lock )
2    //lint -sem( unlock, thread_unlock )
3    //lint -u   unit-check
4    enum meal { none, turkey, veggie };
5    extern struct Mutex &mutex;
6    void lock(Mutex&), unlock(Mutex&);
7    extern int num_turkeys;
8    bool wants_turkey(void);
9    bool turkey_available(void);
10   meal get_meal()
11       {
12       meal kind = none;
13       if( wants_turkey() &&
14           turkey_available() )
15           {
16           lock(mutex);
17           if( num_turkeys > 0 )
18               {
19               num_turkeys--;
20               kind = turkey;
21               }
22           }
23       if( kind == none ) kind = veggie;
24       unlock(mutex);
25       return kind;
26       }

A thanksgiving meal dispenser contains a thread to provide a turkey dinner for all who want turkey if turkey is available and provide a veggie meal otherwise. But something is going wrong.


bug456.cpp lint Output

--- Module:   bug456.cpp (C++)
    _
    if( kind == none ) kind = veggie;
bug456.cpp(23) : Warning 456: Two execution paths are being combined with
    different mutex lock states

Reference Manual Explanation


456    Two execution paths are being combined with different mutex lock
       states  -- It is the purpose of this message to make absolutely
       certain that every lock has a corresponding unlock in the same
       unbroken sequence of code in the same function.

       Execution paths can be combined at the end of an if statement,
       switch statement, or the begining of while, for and do
       statements, a label (target of goto), etc.  In all these cases we
       check to make sure that the mutex lock states are the same.  For
       example:

                 //lint -sem( lock, thread_lock )
                 void f( bool x )
                     {
                     if( x ) lock();
                     // Warning 456 issued here
                     ...

       It could be argued that if an unlock() call would appear under
       control of the very same bool x in the example above then all
       would be well.  And if this is your coding style you are free to
       turn this message off.  But errors in mutex locking have such
       horrible programming consequences as to suggest especially strong
       measures to assure code correctness.  We recommend, for example:

                 //lint -sem( lock, thread_lock )
                 //lint -sem( unlock, thread_unlock )
                 void f( bool x )
                     {
                     if( x )
                         { lock(); /* something */; unlock(); }
                     else
                         { /* something */ }
                     }

       If the 'something' that is being executed is sufficently complex,
       then it can be made into a function.


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


Previous Bug - Bug #445 - October 2010

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 2010, Gimpel Software, All rights reserved.