|
868 | 868 | and the two replacement lists are identical, |
869 | 869 | otherwise the program is ill-formed. |
870 | 870 |
|
| 871 | +\pnum |
| 872 | +\begin{example} |
| 873 | +The following sequence is valid: |
| 874 | +\begin{codeblock} |
| 875 | +#define OBJ_LIKE (1-1) |
| 876 | +#define OBJ_LIKE @\tcode{/* white space */ (1-1) /* other */}@ |
| 877 | +#define FUNC_LIKE(a) ( a ) |
| 878 | +#define FUNC_LIKE( a )( @\tcode{/* note the white space */ \textbackslash}@ |
| 879 | + a @\tcode{/* other stuff on this line}@ |
| 880 | + @\tcode{*/}@ ) |
| 881 | +\end{codeblock} |
| 882 | +But the following redefinitions are invalid: |
| 883 | +\begin{codeblock} |
| 884 | +#define OBJ_LIKE (0) // different token sequence |
| 885 | +#define OBJ_LIKE (1 - 1) // different white space |
| 886 | +#define FUNC_LIKE(b) ( a ) // different parameter usage |
| 887 | +#define FUNC_LIKE(b) ( b ) // different parameter spelling |
| 888 | +\end{codeblock} |
| 889 | +\end{example} |
| 890 | + |
871 | 891 | \pnum |
872 | 892 | \indextext{macro!replacement list}% |
873 | 893 | There shall be white-space between the identifier and the replacement list |
|
938 | 958 | The replacement list is then rescanned for more macro names as |
939 | 959 | specified below. |
940 | 960 |
|
| 961 | +\pnum |
| 962 | +\begin{example} |
| 963 | +The simplest use of this facility is to define a ``manifest constant'', |
| 964 | +as in |
| 965 | +\begin{codeblock} |
| 966 | +#define TABSIZE 100 |
| 967 | +int table[TABSIZE]; |
| 968 | +\end{codeblock} |
| 969 | +\end{example} |
| 970 | + |
941 | 971 | \pnum |
942 | 972 | A preprocessing directive of the form |
943 | 973 | \begin{ncsimplebnf} |
|
983 | 1013 | arguments that would otherwise act as preprocessing directives,\footnote{A \grammarterm{conditionally-supported-directive} is a preprocessing directive regardless of whether the implementation supports it.} |
984 | 1014 | the behavior is undefined. |
985 | 1015 |
|
| 1016 | +\pnum |
| 1017 | +\begin{example} |
| 1018 | +The following defines a function-like |
| 1019 | +macro whose value is the maximum of its arguments. |
| 1020 | +It has the disadvantages of evaluating one or the other of its arguments |
| 1021 | +a second time |
| 1022 | +(including |
| 1023 | +\indextext{side effects}% |
| 1024 | +side effects) |
| 1025 | +and generating more code than a function if invoked several times. |
| 1026 | +It also cannot have its address taken, |
| 1027 | +as it has none. |
| 1028 | + |
| 1029 | +\begin{codeblock} |
| 1030 | +#define max(a, b) ((a) > (b) ? (a) : (b)) |
| 1031 | +\end{codeblock} |
| 1032 | + |
| 1033 | +The parentheses ensure that the arguments and |
| 1034 | +the resulting expression are bound properly. |
| 1035 | +\end{example} |
| 1036 | + |
986 | 1037 | \pnum |
987 | 1038 | \indextext{macro!function-like!arguments}% |
988 | 1039 | If there is a \tcode{...} immediately preceding the \tcode{)} in the |
|
1040 | 1091 | shall be treated as if it were a parameter, and the variable arguments shall form |
1041 | 1092 | the preprocessing tokens used to replace it. |
1042 | 1093 |
|
| 1094 | +\pnum |
| 1095 | +\begin{example} |
| 1096 | +\begin{codeblock} |
| 1097 | +#define debug(...) fprintf(stderr, @\mname{VA_ARGS}@) |
| 1098 | +#define showlist(...) puts(#@\mname{VA_ARGS}@) |
| 1099 | +#define report(test, ...) ((test) ? puts(#test) : printf(@\mname{VA_ARGS}@)) |
| 1100 | +debug("Flag"); |
| 1101 | +debug("X = %d\n", x); |
| 1102 | +showlist(The first, second, and third items.); |
| 1103 | +report(x>y, "x is %d but y is %d", x, y); |
| 1104 | +\end{codeblock} |
| 1105 | +results in |
| 1106 | +\begin{codeblock} |
| 1107 | +fprintf(stderr, "Flag"); |
| 1108 | +fprintf(stderr, "X = %d\n", x); |
| 1109 | +puts("The first, second, and third items."); |
| 1110 | +((x>y) ? puts("x>y") : printf("x is %d but y is %d", x, y)); |
| 1111 | +\end{codeblock} |
| 1112 | +\end{example} |
| 1113 | + |
1043 | 1114 | \pnum |
1044 | 1115 | \indextext{__VA_OPT__@\mname{VA_OPT}}% |
1045 | 1116 | The identifier \mname{VA_OPT} |
|
1194 | 1265 | \tcode{\#\#} |
1195 | 1266 | operators is unspecified. |
1196 | 1267 |
|
| 1268 | +\pnum |
| 1269 | +\begin{example} |
| 1270 | +The sequence |
| 1271 | +\begin{codeblock} |
| 1272 | +#define str(s) # s |
| 1273 | +#define xstr(s) str(s) |
| 1274 | +#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", @\textbackslash@ |
| 1275 | + x ## s, x ## t) |
| 1276 | +#define INCFILE(n) vers ## n |
| 1277 | +#define glue(a, b) a ## b |
| 1278 | +#define xglue(a, b) glue(a, b) |
| 1279 | +#define HIGHLOW "hello" |
| 1280 | +#define LOW LOW ", world" |
| 1281 | + |
| 1282 | +debug(1, 2); |
| 1283 | +fputs(str(strncmp("abc@\textbackslash@0d", "abc", '@\textbackslash@4') // this goes away |
| 1284 | + == 0) str(: @\atsign\textbackslash@n), s); |
| 1285 | +#include xstr(INCFILE(2).h) |
| 1286 | +glue(HIGH, LOW); |
| 1287 | +xglue(HIGH, LOW) |
| 1288 | +\end{codeblock} |
| 1289 | +results in |
| 1290 | +\begin{codeblock} |
| 1291 | +printf("x" "1" "= %d, x" "2" "= %s", x1, x2); |
| 1292 | +fputs("strncmp(@\textbackslash@"abc@\textbackslash\textbackslash@0d@\textbackslash@", @\textbackslash@"abc@\textbackslash@", '@\textbackslash\textbackslash@4') == 0" ": @\atsign\textbackslash@n", s); |
| 1293 | +#include "vers2.h" @\textrm{(\textit{after macro replacement, before file access})}@ |
| 1294 | +"hello"; |
| 1295 | +"hello" ", world" |
| 1296 | +\end{codeblock} |
| 1297 | +or, after concatenation of the character string literals, |
| 1298 | +\begin{codeblock} |
| 1299 | +printf("x1= %d, x2= %s", x1, x2); |
| 1300 | +fputs("strncmp(@\textbackslash@"abc@\textbackslash\textbackslash@0d@\textbackslash@", @\textbackslash@"abc@\textbackslash@", '@\textbackslash\textbackslash@4') == 0: @\atsign\textbackslash@n", s); |
| 1301 | +#include "vers2.h" @\textrm{(\textit{after macro replacement, before file access})}@ |
| 1302 | +"hello"; |
| 1303 | +"hello, world" |
| 1304 | +\end{codeblock} |
| 1305 | + |
| 1306 | +Space around the \tcode{\#} and \tcode{\#\#} tokens in the macro definition |
| 1307 | +is optional. |
| 1308 | +\end{example} |
| 1309 | + |
| 1310 | +\pnum |
1197 | 1311 | \begin{example} |
1198 | 1312 | In the following fragment: |
1199 | 1313 |
|
|
1220 | 1334 | \tcode{\#\#} operator. |
1221 | 1335 | \end{example} |
1222 | 1336 |
|
| 1337 | +\pnum |
| 1338 | +\begin{example} |
| 1339 | +To illustrate the rules for placemarker preprocessing tokens, the sequence |
| 1340 | +\begin{codeblock} |
| 1341 | +#define t(x,y,z) x ## y ## z |
| 1342 | +int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), |
| 1343 | + t(10,,), t(,11,), t(,,12), t(,,) }; |
| 1344 | +\end{codeblock} |
| 1345 | +results in |
| 1346 | +\begin{codeblock} |
| 1347 | +int j[] = { 123, 45, 67, 89, |
| 1348 | + 10, 11, 12, }; |
| 1349 | +\end{codeblock} |
| 1350 | +\end{example} |
| 1351 | + |
1223 | 1352 | \rSec2[cpp.rescan]{Rescanning and further replacement}% |
1224 | 1353 | \indextext{macro!rescanning and replacement}% |
1225 | 1354 | \indextext{rescanning and replacement|see{macro, rescanning and replacement}} |
|
1231 | 1360 | subsequent preprocessing tokens of the source file, for more macro names |
1232 | 1361 | to replace. |
1233 | 1362 |
|
| 1363 | +\pnum |
| 1364 | +\begin{example} |
| 1365 | +The sequence |
| 1366 | +\begin{codeblock} |
| 1367 | +#define x 3 |
| 1368 | +#define f(a) f(x * (a)) |
| 1369 | +#undef x |
| 1370 | +#define x 2 |
| 1371 | +#define g f |
| 1372 | +#define z z[0] |
| 1373 | +#define h g(~ |
| 1374 | +#define m(a) a(w) |
| 1375 | +#define w 0,1 |
| 1376 | +#define t(a) a |
| 1377 | +#define p() int |
| 1378 | +#define q(x) x |
| 1379 | +#define r(x,y) x ## y |
| 1380 | +#define str(x) # x |
| 1381 | + |
| 1382 | +f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); |
| 1383 | +g(x+(3,4)-w) | h 5) & m |
| 1384 | + (f)^m(m); |
| 1385 | +p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; |
| 1386 | +char c[2][6] = { str(hello), str() }; |
| 1387 | +\end{codeblock} |
| 1388 | +results in |
| 1389 | +\begin{codeblock} |
| 1390 | +f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); |
| 1391 | +f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); |
| 1392 | +int i[] = { 1, 23, 4, 5, }; |
| 1393 | +char c[2][6] = { "hello", "" }; |
| 1394 | +\end{codeblock} |
| 1395 | +\end{example} |
| 1396 | + |
1234 | 1397 | \pnum |
1235 | 1398 | If the name of the macro being replaced is found during this scan of |
1236 | 1399 | the replacement list |
|
1274 | 1437 | It is ignored if the specified identifier is not currently defined as |
1275 | 1438 | a macro name. |
1276 | 1439 |
|
1277 | | -\pnum |
1278 | | -\begin{example} |
1279 | | -The simplest use of this facility is to define a ``manifest constant'', |
1280 | | -as in |
1281 | | -\begin{codeblock} |
1282 | | -#define TABSIZE 100 |
1283 | | -int table[TABSIZE]; |
1284 | | -\end{codeblock} |
1285 | | -\end{example} |
1286 | | - |
1287 | | -\pnum |
1288 | | -\begin{example} |
1289 | | -The following defines a function-like |
1290 | | -macro whose value is the maximum of its arguments. |
1291 | | -It has the advantages of working for any compatible types of the arguments |
1292 | | -and of generating in-line code without the overhead of function calling. |
1293 | | -It has the disadvantages of evaluating one or the other of its arguments |
1294 | | -a second time |
1295 | | -(including |
1296 | | -\indextext{side effects}% |
1297 | | -side effects) |
1298 | | -and generating more code than a function if invoked several times. |
1299 | | -It also cannot have its address taken, |
1300 | | -as it has none. |
1301 | | - |
1302 | | -\begin{codeblock} |
1303 | | -#define max(a, b) ((a) > (b) ? (a) : (b)) |
1304 | | -\end{codeblock} |
1305 | | - |
1306 | | -The parentheses ensure that the arguments and |
1307 | | -the resulting expression are bound properly. |
1308 | | -\end{example} |
1309 | | - |
1310 | | -\pnum |
1311 | | -\begin{example} |
1312 | | -To illustrate the rules for redefinition and reexamination, |
1313 | | -the sequence |
1314 | | -\begin{codeblock} |
1315 | | -#define x 3 |
1316 | | -#define f(a) f(x * (a)) |
1317 | | -#undef x |
1318 | | -#define x 2 |
1319 | | -#define g f |
1320 | | -#define z z[0] |
1321 | | -#define h g(~ |
1322 | | -#define m(a) a(w) |
1323 | | -#define w 0,1 |
1324 | | -#define t(a) a |
1325 | | -#define p() int |
1326 | | -#define q(x) x |
1327 | | -#define r(x,y) x ## y |
1328 | | -#define str(x) # x |
1329 | | - |
1330 | | -f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); |
1331 | | -g(x+(3,4)-w) | h 5) & m |
1332 | | - (f)^m(m); |
1333 | | -p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; |
1334 | | -char c[2][6] = { str(hello), str() }; |
1335 | | -\end{codeblock} |
1336 | | -results in |
1337 | | -\begin{codeblock} |
1338 | | -f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); |
1339 | | -f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); |
1340 | | -int i[] = { 1, 23, 4, 5, }; |
1341 | | -char c[2][6] = { "hello", "" }; |
1342 | | -\end{codeblock} |
1343 | | -\end{example} |
1344 | | - |
1345 | | -\pnum |
1346 | | -\begin{example} |
1347 | | -To illustrate the rules for creating character string literals |
1348 | | -and concatenating tokens, |
1349 | | -the sequence |
1350 | | -\begin{codeblock} |
1351 | | -#define str(s) # s |
1352 | | -#define xstr(s) str(s) |
1353 | | -#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", @\textbackslash@ |
1354 | | - x ## s, x ## t) |
1355 | | -#define INCFILE(n) vers ## n |
1356 | | -#define glue(a, b) a ## b |
1357 | | -#define xglue(a, b) glue(a, b) |
1358 | | -#define HIGHLOW "hello" |
1359 | | -#define LOW LOW ", world" |
1360 | | - |
1361 | | -debug(1, 2); |
1362 | | -fputs(str(strncmp("abc@\textbackslash@0d", "abc", '@\textbackslash@4') // this goes away |
1363 | | - == 0) str(: @\atsign\textbackslash@n), s); |
1364 | | -#include xstr(INCFILE(2).h) |
1365 | | -glue(HIGH, LOW); |
1366 | | -xglue(HIGH, LOW) |
1367 | | -\end{codeblock} |
1368 | | -results in |
1369 | | -\begin{codeblock} |
1370 | | -printf("x" "1" "= %d, x" "2" "= %s", x1, x2); |
1371 | | -fputs("strncmp(@\textbackslash@"abc@\textbackslash\textbackslash@0d@\textbackslash@", @\textbackslash@"abc@\textbackslash@", '@\textbackslash\textbackslash@4') == 0" ": @\atsign\textbackslash@n", s); |
1372 | | -#include "vers2.h" @\textrm{(\textit{after macro replacement, before file access})}@ |
1373 | | -"hello"; |
1374 | | -"hello" ", world" |
1375 | | -\end{codeblock} |
1376 | | -or, after concatenation of the character string literals, |
1377 | | -\begin{codeblock} |
1378 | | -printf("x1= %d, x2= %s", x1, x2); |
1379 | | -fputs("strncmp(@\textbackslash@"abc@\textbackslash\textbackslash@0d@\textbackslash@", @\textbackslash@"abc@\textbackslash@", '@\textbackslash\textbackslash@4') == 0: @\atsign\textbackslash@n", s); |
1380 | | -#include "vers2.h" @\textrm{(\textit{after macro replacement, before file access})}@ |
1381 | | -"hello"; |
1382 | | -"hello, world" |
1383 | | -\end{codeblock} |
1384 | | - |
1385 | | -Space around the |
1386 | | -\tcode{\#} |
1387 | | -and |
1388 | | -\tcode{\#\#} |
1389 | | -tokens in the macro definition is optional. |
1390 | | -\end{example} |
1391 | | - |
1392 | | -\pnum |
1393 | | -\begin{example} |
1394 | | -To illustrate the rules for placemarker preprocessing tokens, the sequence |
1395 | | -\begin{codeblock} |
1396 | | -#define t(x,y,z) x ## y ## z |
1397 | | -int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), |
1398 | | - t(10,,), t(,11,), t(,,12), t(,,) }; |
1399 | | -\end{codeblock} |
1400 | | -results in |
1401 | | -\begin{codeblock} |
1402 | | -int j[] = { 123, 45, 67, 89, |
1403 | | - 10, 11, 12, }; |
1404 | | -\end{codeblock} |
1405 | | -\end{example} |
1406 | | - |
1407 | | -\pnum |
1408 | | -\begin{example} |
1409 | | -To demonstrate the redefinition rules, |
1410 | | -the following sequence is valid. |
1411 | | - |
1412 | | -\begin{codeblock} |
1413 | | -#define OBJ_LIKE (1-1) |
1414 | | -#define OBJ_LIKE @\tcode{/* white space */ (1-1) /* other */}@ |
1415 | | -#define FUNC_LIKE(a) ( a ) |
1416 | | -#define FUNC_LIKE( a )( @\tcode{/* note the white space */ \textbackslash}@ |
1417 | | - a @\tcode{/* other stuff on this line}@ |
1418 | | - @\tcode{*/}@ ) |
1419 | | -\end{codeblock} |
1420 | | - |
1421 | | -But the following redefinitions are invalid: |
1422 | | -\begin{codeblock} |
1423 | | -#define OBJ_LIKE (0) // different token sequence |
1424 | | -#define OBJ_LIKE (1 - 1) // different white space |
1425 | | -#define FUNC_LIKE(b) ( a ) // different parameter usage |
1426 | | -#define FUNC_LIKE(b) ( b ) // different parameter spelling |
1427 | | -\end{codeblock} |
1428 | | -\end{example} |
1429 | | - |
1430 | | -\pnum |
1431 | | -\begin{example} |
1432 | | -Finally, to show the variable argument list macro facilities: |
1433 | | -\begin{codeblock} |
1434 | | -#define debug(...) fprintf(stderr, @\mname{VA_ARGS}@) |
1435 | | -#define showlist(...) puts(#@\mname{VA_ARGS}@) |
1436 | | -#define report(test, ...) ((test) ? puts(#test) : printf(@\mname{VA_ARGS}@)) |
1437 | | -debug("Flag"); |
1438 | | -debug("X = %d\n", x); |
1439 | | -showlist(The first, second, and third items.); |
1440 | | -report(x>y, "x is %d but y is %d", x, y); |
1441 | | -\end{codeblock} |
1442 | | -results in |
1443 | | -\begin{codeblock} |
1444 | | -fprintf(stderr, "Flag"); |
1445 | | -fprintf(stderr, "X = %d\n", x); |
1446 | | -puts("The first, second, and third items."); |
1447 | | -((x>y) ? puts("x>y") : printf("x is %d but y is %d", x, y)); |
1448 | | - |
1449 | | -\end{codeblock} |
1450 | | -\end{example} |
1451 | 1440 | \indextext{macro!replacement|)} |
1452 | 1441 |
|
1453 | 1442 | \rSec1[cpp.line]{Line control}% |
|
0 commit comments