// filename:c2011-6-10-3-5-ex.c // original examples and/or notes: // (c) ISO/IEC JTC1 SC22 WG14 N1570, April 12, 2011 // http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf // C2011 6.10.3.5 Scope of macro definitions // compile and output mechanism: // (c) Ogawa Kiyoshi, kaizen@gifu-u.ac.jp, December.29, 2013 // compile errors and/or wornings: // 1 (c) Apple LLVM version 4.2 (clang-425.0.27) (based on LLVM 3.2svn) // Target: x86_64-apple-darwin11.4.2 //Thread model: posix // (c) LLVM 2003-2009 University of Illinois at Urbana-Champaign. // 2 gcc-4.9 (GCC) 4.9.0 20131229 (experimental) // Copyright (C) 2013 Free Software Foundation, Inc. #include #include #include //int f(int); // Example 1 #define TABSIZE 100 int table[TABSIZE]; // Example 2 #define max(a, b) ((a) > (b) ? (a) : (b)) // Example 3 #define x 3 #define f(a) f(x * (a)) #undef x #define x 2 #define g f #define z z[0] #define h2 g(~ #define m(a) a(w) #define w 0,1 #define t(a) a #define p() int #define q(x) x #define r(x,y) x ## y #define str(x) # x void func1(void){ int y,z,z2[5]; f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); g(x+(3,4)-w) | h2 5) & m (f)^m(m); p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; char c[2][6] = { str(hello), str() }; //f(2 * (y+1)) + f(2 * (f(2 * (z2[0])))) % f(2 * (0)) + t(1); //f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); //int i2[] = { 1, 23, 4, 5, }; //char c2[2][6] = { "hello", "" }; } // Example 4 //#define str(s) # s #define xstr(s) str(s) #define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \ x ## s, x ## t) #define INCFILE(n) vers ## n #define glue(a, b) a ## b #define xglue(a, b) glue(a, b) #define HIGHLOW "hello" #define LOW LOW ", world" void func2(void){ int x1,x2; char * s; debug(1, 2); fputs(str(strncmp("abc\0d", "abc", '\4') /* this goes away*/ == 0) str(: @\n), s); glue(HIGH, LOW); xglue(HIGH, LOW); } #include xstr(INCFILE(2).h) //printf("x" "1" "= %d, x" "2" "= %s", x1, x2); //fputs( //"strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", // s); //#include "vers2.h" (after macro replacement, before file access) //void func4(void){ //int x1,x2; //char * s; //"hello"; //"hello" ", world" //printf("x1= %d, x2= %s", x1, x2); //fputs( //"strncmp(\"abc\\0d\", \"abc\", '\\4') == 0: @\n", // s); //} //#include "vers2.h" (after macro replacement, before file access) //"hello"; //"hello, world" // Example 5 #define t2(x,y,z) x ## y ## z int j[] = { t2(1,2,3), t2(,4,5), t2(6,,7), t2(8,9,),t2(10,,), t2(,11,), t2(,,12), t2(,,) }; //int j[] = { 123, 45, 67, 89, //10, 11, 12, }; //EXAMPLE 6 To demonstrate the redefinition rules, the following sequence is valid. #define OBJ_LIKE (1-1) #define OBJ_LIKE /* white space */ (1-1) /* other */ #define FUNC_LIKE(a) ( a ) #define FUNC_LIKE( a )( /* note the white space */ \ a /* other stuff on this line*/ ) //#define OBJ_LIKE (0) // different token sequence //#define OBJ_LIKE (1 - 1) // different white space //#define FUNC_LIKE(b) ( a ) // different parameter usage //#define FUNC_LIKE(b) ( b ) // different parameter spelling // EXAMPLE 7 Finally, to show the variable argument list macro facilities: #define debug2(...) fprintf(stderr, __VA_ARGS__) #define showlist(...) puts(#__VA_ARGS__) #define report(test, ...) ((test)?puts(#test):\ printf(__VA_ARGS__)) int main(void) { int y; debug2("Flag"); debug2("X = %d\n", x); showlist(The first, second, and third items.); report(x>y, "x is %d but y is %d", x, y); //fprintf(stderr, "Flag" ); //fprintf(stderr, "X = %d\n", x ); //puts( "The first, second, and third items." ); //((x>y)?puts("x>y"): //printf("x is %d but y is %d", x, y)); return printf("6.10.3.5 Scope of macro definitions \n"); } // output may be