A Practical Approach to Programming With Assertions Ken Bell Christian-Albrechts Universität Kiel Department of Computer Science and Applied Mathematics Real-Time Systems and Embedded Systems Group July 5, 2005
Main Features Syntax Samples Customizing the Behaviour Type A: Function Interface Declarations Type B: Specification of Function Bodies
Assertions Outline first mentioned in 1967.
Assertions first mentioned in 1967. are formal constraints on software system behaviour.
Assertions first mentioned in 1967. are formal constraints on software system behaviour. specify what a software system is supposed to do rather than how it is to do it.
Assertions first mentioned in 1967. are formal constraints on software system behaviour. specify what a software system is supposed to do rather than how it is to do it. give an overview of the logical meaning of a function.
Availability of Assertions Basic features are available in most common programming languages like C, C++, Java and other
Availability of Assertions Basic features are available in most common programming languages like C, C++, Java and other e.g. in C the macro assert
Availability of Assertions Basic features are available in most common programming languages like C, C++, Java and other e.g. in C the macro assert #define a s s e r t ( ex ) \ ( ( ex )? 1 : \ ( e p r i n t f ( "Failed assertion " #ex \ " at line %d of \%s". \ n", \ LINE, FILE ), abort (), 0))
Usage of Assertions Outline Assertions are a basic concept in Design by Contract by Bertrand Meyer
Usage of Assertions Assertions are a basic concept in Design by Contract by Bertrand Meyer Testdriven Development as part of Extreme Programmings
Why are assertions used rather seldom?
Why are assertions used rather seldom? The tools for programming with assertions don t meet the need of average developers
Why are assertions used rather seldom? The tools for programming with assertions don t meet the need of average developers Customizing messages not possible
Why are assertions used rather seldom? The tools for programming with assertions don t meet the need of average developers Customizing messages not possible Enabling or disabling checking at runtime not possible
Why are assertions used rather seldom? The tools for programming with assertions don t meet the need of average developers Customizing messages not possible Enabling or disabling checking at runtime not possible The training gives no or little attention on assertions. So, developers have no
Why are assertions used rather seldom? The tools for programming with assertions don t meet the need of average developers Customizing messages not possible Enabling or disabling checking at runtime not possible The training gives no or little attention on assertions. So, developers have no clue what kinds of assertions are most effective in certain situations
Why are assertions used rather seldom? The tools for programming with assertions don t meet the need of average developers Customizing messages not possible Enabling or disabling checking at runtime not possible The training gives no or little attention on assertions. So, developers have no clue what kinds of assertions are most effective in certain situations idea what kind of checks to specify in assertions
Outline Main Features Syntax Samples Customizing the Behaviour The Annotation Pre Processor was designed to make assertions a natural and practical aid to software development. The main features of are
Outline Main Features Syntax Samples Customizing the Behaviour The Annotation Pre Processor was designed to make assertions a natural and practical aid to software development. The main features of are replacement of the standard preprocessor
Outline Main Features Syntax Samples Customizing the Behaviour The Annotation Pre Processor was designed to make assertions a natural and practical aid to software development. The main features of are replacement of the standard preprocessor flexibility in what information the error messages return
Outline Main Features Syntax Samples Customizing the Behaviour The Annotation Pre Processor was designed to make assertions a natural and practical aid to software development. The main features of are replacement of the standard preprocessor flexibility in what information the error messages return flexibility in how much checking is done by specifying runlevels
Outline Main Features Syntax Samples Customizing the Behaviour The Annotation Pre Processor was designed to make assertions a natural and practical aid to software development. The main features of are replacement of the standard preprocessor flexibility in what information the error messages return flexibility in how much checking is done by specifying runlevels Assertions are syntactically replaced by standard C code.
Outline Main Features Syntax Samples Customizing the Behaviour The Annotation Pre Processor was designed to make assertions a natural and practical aid to software development. The main features of are replacement of the standard preprocessor flexibility in what information the error messages return flexibility in how much checking is done by specifying runlevels Assertions are syntactically replaced by standard C code. Quantified expressions are translated into for-loops.
Syntax Outline Main Features Syntax Samples Customizing the Behaviour Annotations are written in extended comments /*@... @*/
Syntax Outline Main Features Syntax Samples Customizing the Behaviour Annotations are written in extended comments /*@... @*/ Constraints are specified using C language.
Syntax Outline Main Features Syntax Samples Customizing the Behaviour Annotations are written in extended comments /*@... @*/ Constraints are specified using C language. Assertions must not have sideeffects. Usage of ++ and - - is disallowed.
Syntax Cont d Outline Main Features Syntax Samples Customizing the Behaviour recognizes the following keywords
Syntax Cont d Outline Main Features Syntax Samples Customizing the Behaviour recognizes the following keywords assume - precondition
Syntax Cont d Outline Main Features Syntax Samples Customizing the Behaviour recognizes the following keywords assume - precondition promise - postcondition
Syntax Cont d Outline Main Features Syntax Samples Customizing the Behaviour recognizes the following keywords assume - precondition promise - postcondition return - constraint on the return value
Syntax Cont d Outline Main Features Syntax Samples Customizing the Behaviour recognizes the following keywords assume - precondition promise - postcondition return - constraint on the return value assert - specifies a constraint as an intermediate state of a function body
Syntax Cont d Outline Main Features Syntax Samples Customizing the Behaviour The C language is enhanced by
Syntax Cont d Outline Main Features Syntax Samples Customizing the Behaviour The C language is enhanced by introducing exestential and universal quantifiers
Syntax Cont d Outline Main Features Syntax Samples Customizing the Behaviour The C language is enhanced by introducing exestential and universal quantifiers the operator in.
Syntax Example Main Features Syntax Samples Customizing the Behaviour i n t p o s s q u a r e r o o t ( x ) i n t x ; / @ assume x >= 0 ; r e t u r n y where y >= 0 ; r e t u r n y where y y <= x && x < ( y +1) ( y +1); @/ {.... }
Syntax Example 2 Main Features Syntax Samples Customizing the Behaviour void swap ( x, y ) i n t x ; i n t y ; / @ assume x && y && x!= y ; promise x == i n y ; promise y == i n x ; @ / {... / @ a s s e r t y == i n x ; @ /...
Customizing s Behaviour Main Features Syntax Samples Customizing the Behaviour Diagnostic information can be customized.
Customizing s Behaviour Main Features Syntax Samples Customizing the Behaviour Diagnostic information can be customized. Can give informations unique to the context
Customizing s Behaviour Main Features Syntax Samples Customizing the Behaviour Diagnostic information can be customized. Can give informations unique to the context provides the following macros ANNONAME, FILE, ANNOLINE and FUNCTION.
Customizing s Behaviour Main Features Syntax Samples Customizing the Behaviour Diagnostic information can be customized. Can give informations unique to the context provides the following macros ANNONAME, FILE, ANNOLINE and FUNCTION. Debug levels can be introduced.
Customizing the Violation Message Main Features Syntax Samples Customizing the Behaviour promise x == i n y { p r i n t f ( "%s invalid: file %s, ", ANNONAME, F I L E ) ; p r i n t f ( "line %d, function %s:\n", ANNOLINE, FUNCTION ) ; p r i n t f ( "out *x == %d, out *y == %d\n", x, y ) ; }
Helped to Classify Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Rosenblum used on many systems.
Helped to Classify Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Rosenblum used on many systems. leads to classification.
Type A: Function Interface Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Validate the behaviour of
Type A: Function Interface Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Validate the behaviour of arguments,
Type A: Function Interface Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Validate the behaviour of arguments, return values and
Type A: Function Interface Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Validate the behaviour of arguments, return values and global states.
Type A: Function Interface Declarations Type B: Specification of Function Bodies Overview of Specification of Function Interface Types Assertion Code Description I Specification of Function Interfaces I1 Consistency Between Arguments I2 Dependency of Return Value on Arguments I3 Effect on Global State I4 Context in Which Function is Called I5 Frame Specifications I6 Subrange Membership of Data I7 Enumeration Membership of Data I8 Non-Null Pointers Table: Summary of Classification of Assertions (Part 1)
Consistency Between Arguments Type A: Function Interface Declarations Type B: Specification of Function Bodies Arguments of each function are often interdependent.
Consistency Between Arguments Type A: Function Interface Declarations Type B: Specification of Function Bodies Arguments of each function are often interdependent. Specifying these dependencies is cumbersome if possible at all.
Consistency Between Arguments Type A: Function Interface Declarations Type B: Specification of Function Bodies Arguments of each function are often interdependent. Specifying these dependencies is cumbersome if possible at all. Solution: Preconditions.
Sample for Interdependent Arguments Type A: Function Interface Declarations Type B: Specification of Function Bodies enum Token Kind { i d e n t i f i e r, number, s t r i n g } ; void s t o r e t o k e n { kind, token } enum Token Kind k i n d ; char token ; / @ assume @ /... ( k i n d == i d e n t i f i e r && token [ 0 ] >= a && token [ 0 ] <= z ) ( k i n d == number && token [ 0 ] >= 0 && token [ 0 ] <= 9 ) ( k i n d == s t r i n g && token [ 0 ] == ) ;
More Classes of Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies
More Classes of Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Dependency of Return Value on Arguments
More Classes of Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Dependency of Return Value on Arguments return y where y y <= x && x < (y+1) (y+1);
More Classes of Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Dependency of Return Value on Arguments return y where y y <= x && x < (y+1) (y+1); Effect on global state.
More Classes of Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Dependency of Return Value on Arguments return y where y y <= x && x < (y+1) (y+1); Effect on global state. Calling Context.
Calling Context: Sample Type A: Function Interface Declarations Type B: Specification of Function Bodies void p r i n t w a r n i n g ( code, l i n e, f i l e ) i n t code ; i n t l i n e ; char f i l e ; / @ assume w a r n i n g s o n ; @ /
Frame Specifications Outline Type A: Function Interface Declarations Type B: Specification of Function Bodies Explicitly state if an argument or global variable is to be left unchanged.
Frame Specifications Outline Type A: Function Interface Declarations Type B: Specification of Function Bodies Explicitly state if an argument or global variable is to be left unchanged. void d e l e t e n a m e ( name ) char name ; / @ assume hashget ( symbols, name ) ; promise! hashget ( symbols, name ) ; promise strcmp ( i n name, i n s t r d u p ( name ) ) == 0 ; @ /
Subrange Membership of Data Type A: Function Interface Declarations Type B: Specification of Function Bodies Overrunning array bounds is very common.
Subrange Membership of Data Type A: Function Interface Declarations Type B: Specification of Function Bodies Overrunning array bounds is very common. Use Postconditions to ensure, that e.g. arrays were treated correctly.
More Classes of Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Enumeration Membership of Data The weak type system leads to problems with enumeration types.
More Classes of Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Enumeration Membership of Data The weak type system leads to problems with enumeration types. E.g. integers and literals as enumerators are interchangeable.
More Classes of Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Enumeration Membership of Data The weak type system leads to problems with enumeration types. E.g. integers and literals as enumerators are interchangeable. Use assertions to ensure that the variables of an enumeration type contain valid values of the type.
More Classes of Assertions Type A: Function Interface Declarations Type B: Specification of Function Bodies Enumeration Membership of Data The weak type system leads to problems with enumeration types. E.g. integers and literals as enumerators are interchangeable. Use assertions to ensure that the variables of an enumeration type contain valid values of the type. Non-Null Pointers Assertions that state that a pointer is non-null have to be specified before all other assertions that use the same pointer.
Type A: Function Interface Declarations Type B: Specification of Function Bodies Overview of Specification of Function Interface Types Assertion Code B B1 B2 B3 B4 Description Specification of Function Bodies Condition of Else Part of If Statement Condition of Default Branch of Switch Statement Consistency Between Related Data Intermediate Snapshot of Computation Table: Summary of Classification of Assertions (Part 2)
Type A: Function Interface Declarations Type B: Specification of Function Bodies Condition of the Else Part of Complex If Statements C programs often use extensive control statements
Type A: Function Interface Declarations Type B: Specification of Function Bodies Condition of the Else Part of Complex If Statements C programs often use extensive control statements Use assertions to explicitly specify the implicit condition of the final else statement in an if statement.
Type A: Function Interface Declarations Type B: Specification of Function Bodies Condition of the Else Part of Complex If Statements C programs often use extensive control statements Use assertions to explicitly specify the implicit condition of the final else statement in an if statement. A default condition is often intended to be stronger than the simple negation of the disjunction of the if conditions.
Type A: Function Interface Declarations Type B: Specification of Function Bodies Condition of the Default Case of a Switch Statement If a switch statements contains a default case, explicitly state the condition, otherwise state a condition that always evaluates to false.
Type A: Function Interface Declarations Type B: Specification of Function Bodies Condition of the Default Case of a Switch Statement If a switch statements contains a default case, explicitly state the condition, otherwise state a condition that always evaluates to false. switch ( k i n d ) { case i d e n t i f i e r :... case number :... case s t r i n g :... d e f a u l t : / @ a s s e r t 0 ; @ / break }
More Function Body Constraints Type A: Function Interface Declarations Type B: Specification of Function Bodies Consistency of related data.
More Function Body Constraints Type A: Function Interface Declarations Type B: Specification of Function Bodies Consistency of related data. Intermediate snapshot of computation.
Productive D. Rosenblum used to develop YEAST - Yet another Event Action Specification - tool.
Productive D. Rosenblum used to develop YEAST - Yet another Event Action Specification - tool. YEAST consists of 12k loc.
Productive D. Rosenblum used to develop YEAST - Yet another Event Action Specification - tool. YEAST consists of 12k loc. Debug-Executables grew about 3.7% in size but almost no difference in speed.
Productive D. Rosenblum used to develop YEAST - Yet another Event Action Specification - tool. YEAST consists of 12k loc. Debug-Executables grew about 3.7% in size but almost no difference in speed. 19 faults were discovered.
Outline Usage of can help to discover and remove faults.
Usage of can help to discover and remove faults. Generating and implementing assertions is still manual work to do.
Usage of can help to discover and remove faults. Generating and implementing assertions is still manual work to do. Besides being a basic concept in test-driven development, lacks the simplicity of modern bug tracer.
Usage of can help to discover and remove faults. Generating and implementing assertions is still manual work to do. Besides being a basic concept in test-driven development, lacks the simplicity of modern bug tracer. The usage of does not teach what to specify in assertions.
Usage of can help to discover and remove faults. Generating and implementing assertions is still manual work to do. Besides being a basic concept in test-driven development, lacks the simplicity of modern bug tracer. The usage of does not teach what to specify in assertions. The user s knowledge is still needed.
References David S. Rosenblum, A Practical Approach to Programming With Assertions. Wikipedia: Assertions http://www.cs.wustl.edu/ schmidt/pdf/c++-assert4.pdf