|
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