180 likes | 189 Views
TCTI-V2CCPP1-10 C en C++ Programmeren Week 3, les 2 : The preprocessor and other odds and ends (assignment: fagan inspection session). C compilation process. #define MESSAGE ”Hello” int main( void){ printf( "m [%s ] @ %X<br>", MESSAGE, MESSAGE ); f(); }. Separate step
E N D
TCTI-V2CCPP1-10 C en C++ Programmeren Week 3, les 2 : The preprocessor and other odds and ends (assignment: fagan inspection session)
C compilation process #define MESSAGE ”Hello” int main( void){ printf( "m [%s ] @ %X\n", MESSAGE, MESSAGE ); f(); } • Separate step • Can be used by other languages • A powerful but potentially dangerous tool preprocessor void f( void ){ printf( "f [%s ] @ %X\n", ”Hello”, ”Hello” ); } compiler Why that empty line?
Some preprocessor directives #include ”file” - #include <file> #define #ifdef - #ifndef - #elif - #else - #endif #if - #elif - #else - #endif
Some useful predefined macro’s __FILE__ __LINE__ Note: 2 underscores! if( size < 0 ){ printf( ”Fatal error: size below 0 in %s at line %d\n”, __FILE__, __LINE__ ); exit(); }
A macro with parameters #define name( arg1, arg2, … ) expansion #define int_swap( x, y ){ int temp = x; x = y; y = temp; } int a = 1, b = 2; printf( ”a=%d b=%d\n”, a, b ); int_swap( a, b ); printf( ”a=%d b=%d\n”, a, b );
Multiple expansion #define square( x ) ( x * x ) int a = 1; printf( ”a=%d square(a)=%d\n”, a, square(a) ); int b = 1; printf( ”square(b++)=”, square(b++) ); Printf( ”b=%d\n”, b ); • This is a dirty macro. If you want to use it at all, make clear to the reader that it is a macro! #define SQUARE( x ) ( x * x )
More parameter trouble #define double( x ) ( x * 2 ) int a = 1; printf( ”a=%d double(a)=%d\n”, a, double(a) ); int b = 1; printf( ”double(b + 1)=”, double( b + 1 ) ); • In the expansion, ALWAYS put the macro arguments in parenthesis: #define double( x ) ( (x) * 2 )
Multi-line expansion #define TRACE if( trace_enable ) { \ printf( \ ”%s:%d\n”, \ __FILE__, \ __LINE__ \ ); \ } int trace_enable = 0; void f( void ){ trace_enabled = 1; TRACE; printf( ”Hello year %s\n”, 2010 ); TRACE; } • Why no \ after the last } ?? • Note that the \ must be the very last character: even a space after it will cause an error!
An assert macro #define assert( condition ) if( ! (condition) ){ \ printf( \ ”%s:%d Fatal error: assert failed\n”, \ __FILE__, \ __LINE__ \ ); \ exit(); \ } void root( int x ){ assert( x >= 0 ); ... }
Casts (int) (char *) Tells the compiler that the type of an expression must be converted. int n = 4, sum = 3; float average = sum / n; printf( ”average is %f”, average ); int n = 4, sum = 3; float average = sum / (float) n; printf( ”average is %f”, average );
Casts Malloc allocates memory and returns a (void!) pointer to the allocated memory. typedef unsigned int size_t; Void * malloc( size_t size ); char * message = malloc( 132 ); Tell the compiler that it must ‘convert’ the void * to a char *. char * message = (char *) malloc( 132 );
sizeof sizeof( type ) This is a macro-like C construct that is replaced (by the C compiler) by the size of the type printf( ”char is %2d bytes\n”, sizeof( char ) ); printf( ”short is %2d bytes\n”, sizeof( short int ) ); printf( ”int is %2d bytes\n”, sizeof( int ) ); printf( ”long is %2d bytes\n”, sizeof( long int ) ); printf( ”long long is %2d bytes\n”, sizeof( long long int ) );
A memory allocation macro What did we do wrong? typedef char big_buffer[ 1000 ]; typedef char small_buffer[ 10 ]; big_buffer * buf = ( big_buffer *) malloc( sizeof( small_buffer )); int i; for( i = 0; i < 1000; i++ ){ buf[ i ] = 0; } #define allocate( type ) (( type * ) malloc( sizeof( type ))) big_buffer * buf = malloc( sizeof( small_buffer ));
Macro guidelines Macros are fun, but can also be very dangerous. Do not use a macro when another (C-language level) construct would be equally effective. Obey the basic safe-use rules: parameters in (), statements in {}. Macro’s that fully behave as variables, constants, or functions can be named as such. Macro’s that require the reader to be aware of their nature must be in UPPERCASE.
Fagan assignment 2 - session The moderators will each old an inspection session with their inspectors (in the practicum room or near to it). The allotted time is the 90 minutes for the assignment. In the session the document is scanned and the defects are mentioned - to the level that is deemed practical by the moderator (µ’s are never mentioned). The scanner role (the inspector that reads identifies the next defect) is rotated. The inspectors cross out any (above µ) duplicates.
Fagan assignment 2 - moderator • The moderators • Is the chairman. • Makes sure that the inspectors get equal ‘speaking time’. • Kills any discussions about whether a defect is right or the document or is correct. The aim of the session is that it gets clear what an inspector means, not whether he is right. • Keeps an eye on the allotted time. Use the total document must be handled.
Fagan assignment 2 - output • The inspectors count the number of duplicate defects and note the number of remaining defects on their defect list. • The defect lists and the annotated documents are handed over to the moderators. • The moderators report to the teacher (by email, word template is on sharepoint): • The original number of defects (minor and major separately) found by each inspector (mention the inspectors name and role!). • The total number of defects found, and the total number remaining after duplicates are removed (minor and major separately). • Any other interesting observations, including defects in the input documents.
Fagan assignment 2 – follow-up • This is outside the scope of V2CCPP1, but I strongly suggest that: • Each group reworks its document according to the inspection results, before it is submitted for the project. • The moderator does no rework work himself, but checks the rework (at least for the major defects). • When a major defect is unclear (even to the moderator) you can contact the inspector.