<<

Macros in /C++

Computer Science and Engineering  College of Engineering  The Ohio State University

Lecture 33 Definition

Computer Science and Engineering  The Ohio State University  : #define #define  Example: #define BUFF_SIZE 1000  A newline ends the macro body  Macros can only be 1 line long  Work-around: For longer bodies, use the line character, \  Naming convention: SCREAMING_SNAKE_CASE  Common use: compile-time constant int Buffer[BUFF_SIZE];  Also: #undef GNU gcc Toolchain

Computer Science and Engineering  The Ohio State University  Run only macro : -E  $ gcc –E test.c > test.i  Standard file extension for preprocessed C (C++) is .i (.ii)  More than just expanding macros:  Begins by stripping comments  Concatenates lines marked with \  May collapse white space  Adds markers for filename and line numbers to help connect later errors to original location in source file Text Substitution

Computer Science and Engineering  The Ohio State University  Gcc preprocessor doesn't really care that input is a C program…  Theoretically can be used on any text file  Demo: ulisse.c, ulisse.ii  Caveat: The preprocessor does rely on proper C conventions for tokenizing  Apostrophes will mess things up  In practice: preprocessing something other than C/C++ files with gcc is a hack, it is brittle, and it is probably a bad idea Algorithmic Highlights

Computer Science and Engineering  The Ohio State University  Single pass  Forward references are not expanded  Nested invocation is permitted  Expanded body is rescanned for more invocations  Nested definitions are not permitted  No recursion or mutual recursion  Self references are not further expanded  Circularity (mutual recursion) handled similarly: First cyclic reference is not expanded Nesting Forward References

Computer Science and Engineering  The Ohio State University  Input  Input foo = X; #define SIZE BUFF #define X 4 #define BUFF 1024 bar = X; Mem[SIZE];

 Output  Output foo = X; Mem[1024]; bar = 4; Still Single Pass

Computer Science and Engineering  The Ohio State University  Input #define BUFF 1024 #define SIZE BUFF #undef BUFF #define BUFF 2048 Mem[SIZE];

 Output? Macro Arguments

Computer Science and Engineering  The Ohio State University  Argument list follows name, without spaces #define ()  Example #define INC(X) X++ #define SUM(X,Y) X+Y  Danger: Arithmetic grouping  Macro is doing text substitution, not call  issues may cause surprising problems Problem: Unprotected Body

Computer Science and Engineering  The Ohio State University  Recall ternary operator ( _ ? _ : _ )  Consider #define MAX(X,Y) X > Y ? X : Y  Do these work? a = MAX(b,c); a = MAX(b,c) + 1;  Result of expansion: a = b > c ? b : c; a = b > c ? b : c + 1;  Solution: protect the body #define MAX(X,Y) (X > Y ? X : Y) Problem: Unprotected Args

Computer Science and Engineering  The Ohio State University  Consider another use of MAX macro flag = MAX(b<0,c<0);  A disjunction of the two conditions?  Result of expansion: flag = (b<0 > c<0 ? b<0 : c<0);  Solution: protect the arguments #define MAX(X,Y) ((X) > (Y) ?(X):(Y)) flag = ((b<0) > (c<0) ?(b<0):(c<0)); Conditional Expansion

Computer Science and Engineering  The Ohio State University  Common condition “is this macro (not) defined?” #ifndef BUFF_SIZE #define BUFF_SIZE 1024 #endif /*BUFF_SIZE*/  Application: debugging modes #define DEBUG_ON . . . #ifdef DEBUG_ON printf ( . . . ); #endif /*DEBUG_ON*/  Advantage: No space/time overhead  Disadvantage: Change requires recompiling File Inclusion

Computer Science and Engineering  The Ohio State University  Syntax #include ""  Effect: Contents of inserted at that point

#include “f” Danger: Repeated Inclusion

Computer Science and Engineering  The Ohio State University  Multiple inclusion of the same file can lead to conflicts, eg double declaration  File f1 includes lib1 and lib2  File lib1 includes lib2  Result: f1.i contains two copies of lib2  In the extreme: recursive inclusion  File f1 includes f2  File f2 includes f1 Solution: Conditional

Computer Science and Engineering  The Ohio State University  Protect every file that will be included by other file(s)  Convention  Wrap entire file in #ifndef … #endif  Inside, define a unique macro (1/file)  Example, file cat.h #ifndef CAT_H_PAGS #define CAT_H_PAGS ... #endif /*CAT_H_PAGS*/ Predefined Macros

Computer Science and Engineering  The Ohio State University  Macros provided by the preprocessor  Some are part of ANSI language standard  __FILE__ : current file name  __LINE__ : this line number in current file  __DATE__ / __TIME__ : current date/time  Some are -specific (eg gcc)  __VERSION__  __BASE_FILE__  __INCLUDE_LEVEL__  Example use: Error or debug messages printf("error in %s, line %d\n", __FILE__, __LINE__); Using Arguments in Strings

Computer Science and Engineering  The Ohio State University  ANSI C: Parameter substitution is not performed within quoted strings  Example #define DISP(EXP) \ printf("EXP = %d\n", EXP) DISP(i*j+1)  Result of expansion: printf("EXP = %d\n", i*j+1)  Solution: "Stringizing" operator, # #define DISP(EXP) \ printf(#EXP " = %d\n", EXP)  Result of expansion: printf("i*j+1" " = %d\n", i*j+1) Pitfall: Side effects

Computer Science and Engineering  The Ohio State University  Macros look like function calls  Text substitution means semantics are not the same as function calls  Example: Recall MAX macro #define MAX(X,Y) ((X) > (Y) ?(X):(Y)) a = MAX(b++, c++)  If b = 2, and c = 5 beforehand, what is the result?

// a = ____, b = ____, c = ____ Pitfall: Swallow the Semicolon

Computer Science and Engineering  The Ohio State University  Macro consists of compound statement #define INC(X,Y) {X++; Y++}  Tempting to use macro with semicolon INC(a, b);  However, consider: if (…) INC(a, b); else …  Result: compile-time error  Solution: (notice missing semicolon) #define INC(X, Y) \ do { X++; Y++ } while(0) Summary

Computer Science and Engineering  The Ohio State University  Macro definition with #define  Single pass  No forward references  No nested definitions  Nested invocations expanded (no cycles)  Arguments are permitted  Conditional expansion #ifdef  File inclusion #include  Coding idioms to prevent some mistakes  Protect the body, protect the arguments  Avoid arguments with side effects