Changeset e945826 for doc/refrat
- Timestamp:
- Apr 30, 2016, 2:05:06 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 0638c44, 1048b31, fbfde843
- Parents:
- 8bc4ef8
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/refrat/refrat.tex
r8bc4ef8 re945826 11 11 %% Created On : Wed Apr 6 14:52:25 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sat Apr 9 10:19:12201614 %% Update Count : 813 %% Last Modified On : Sat Apr 30 13:45:40 2016 14 %% Update Count : 29 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 17 17 % requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended 18 19 % red highlighting ®...® (registered trademark sumbol) 20 % blue highlighting ©...© (copyright symbol) 21 % latex escape §...§ (section symbol) 22 % keyword escape ¶...¶ (pilcrow symbol) 23 % math escape $...$ (dollar symbol) 18 24 19 25 \documentclass[openright,twoside]{report} … … 125 131 \CFA's scope rules differ from C's in one major respect: a declaration of an identifier may overload\index{overloading} outer declarations of lexically identical identifiers in the same 126 132 \Index{name space}, instead of hiding them. 127 The outer declaration is hidden if the two declarations have \Index{compatible type}, or if one declares an array type and the other declares a pointer type and the element type and pointed-at type are compatible, or if one has function type and the other is a pointer to a compatible function type, or if one declaration is a \lstinline $type$\use{type} or128 \lstinline $typedef$\use{typedef} declaration and the other is not. The outer declaration becomes133 The outer declaration is hidden if the two declarations have \Index{compatible type}, or if one declares an array type and the other declares a pointer type and the element type and pointed-at type are compatible, or if one has function type and the other is a pointer to a compatible function type, or if one declaration is a \lstinline@type@\use{type} or 134 \lstinline@typedef@\use{typedef} declaration and the other is not. The outer declaration becomes 129 135 \Index{visible} when the scope of the inner declaration terminates. 130 136 \begin{rationale} 131 Hence, a \CFA program can declare an \lstinline $int v$ and a \lstinline$float v$in the same scope;137 Hence, a \CFA program can declare an \lstinline@int v@ and a \lstinline@float v@ in the same scope; 132 138 a {\CC} program can not. 133 139 \end{rationale} … … 143 149 Identifiers with \Index{no linkage} always denote unique entities. 144 150 \begin{rationale} 145 A \CFA program can declare an \lstinline $extern int v$ and an \lstinline$extern float v$;151 A \CFA program can declare an \lstinline@extern int v@ and an \lstinline@extern float v@; 146 152 a C program cannot. 147 153 \end{rationale} … … 166 172 \end{lstlisting} 167 173 168 The type parameters in an instantiation of a generic type must satisfy any constraints in the forall specifier on the type generator declaration, e.g., \lstinline $sumable$.174 The type parameters in an instantiation of a generic type must satisfy any constraints in the forall specifier on the type generator declaration, e.g., \lstinline@sumable@. 169 175 The instantiation then has the semantics that would result if the type parameters were substituted into the type generator declaration by macro substitution. 170 176 … … 227 233 In \CFA, these conversions play a role in overload resolution, and collectively are called the \define{safe arithmetic conversion}s. 228 234 229 Let \ (int_r\) and \(unsigned_r\)be the signed and unsigned integer types with integer conversion rank\index{integer conversion rank}\index{rank|see{integer conversion rank}} $r$.230 Let \ (unsigned_{mr}\)be the unsigned integer type with maximal rank.235 Let \lstinline@int$_r$@ and \lstinline@unsigned$_r$@ be the signed and unsigned integer types with integer conversion rank\index{integer conversion rank}\index{rank|see{integer conversion rank}} $r$. 236 Let \lstinline@unsigned$_{mr}$@ be the unsigned integer type with maximal rank. 231 237 232 238 The following conversions are \emph{direct} safe arithmetic conversions. … … 235 241 The \Index{integer promotion}s. 236 242 \item 237 For every rank $r$ greater than or equal to the rank of \lstinline $int$, conversion from \(int_r\) to \(unsigned_r\).238 \item 239 For every rank $r$ greater than or equal to the rank of \lstinline $int$, where \(int_{r+1}\) exists and can represent all values of \(unsigned_r\), conversion from \(unsigned_r\) to \(int_{r+1}\).240 \item 241 Conversion from \ (unsigned_{mr}\) to \lstinline$float$.243 For every rank $r$ greater than or equal to the rank of \lstinline@int@, conversion from \lstinline@int$_r$@ to \lstinline@unsigned$_r$@. 244 \item 245 For every rank $r$ greater than or equal to the rank of \lstinline@int@, where \lstinline@int$_{r+1}$@ exists and can represent all values of \lstinline@unsigned$_r$@, conversion from \lstinline@unsigned$_r$@ to \lstinline@int$_{r+1}$@. 246 \item 247 Conversion from \lstinline@unsigned$_{mr}$@ to \lstinline@float@. 242 248 \item 243 249 Conversion from an enumerated type to its compatible integer type. 244 250 \item 245 Conversion from \lstinline $float$ to \lstinline$double$, and from \lstinline$double$ to \lstinline$long double$.246 \item 247 Conversion from \lstinline $float _Complex$ to \lstinline$double _Complex$, and from \lstinline$double _Complex$ to \lstinline$long double _Complex$.251 Conversion from \lstinline@float@ to \lstinline@double@, and from \lstinline@double@ to \lstinline@long double@. 252 \item 253 Conversion from \lstinline@float _Complex@ to \lstinline@double _Complex@, and from \lstinline@double _Complex@ to \lstinline@long double _Complex@. 248 254 \begin{sloppypar} 249 255 \item 250 Conversion from \lstinline $float _Imaginary$ to \lstinline$double _Imaginary$, and from \lstinline$double _Imaginary$ to \lstinline$long double$ \lstinline$_Imaginary$, if the implementation supports imaginary types.256 Conversion from \lstinline@float _Imaginary@ to \lstinline@double _Imaginary@, and from \lstinline@double _Imaginary@ to \lstinline@long double _Imaginary@, if the implementation supports imaginary types. 251 257 \end{sloppypar} 252 258 \end{itemize} 253 259 254 If type \lstinline $T$ can be converted to type \lstinline$U$ by a safe direct arithmetic conversion and type \lstinline$U$ can be converted to type \lstinline$V$ by a safe arithmetic conversion, then the conversion from \lstinline$T$ to type \lstinline$V$is an \emph{indirect} safe arithmetic conversion.260 If type \lstinline@T@ can be converted to type \lstinline@U@ by a safe direct arithmetic conversion and type \lstinline@U@ can be converted to type \lstinline@V@ by a safe arithmetic conversion, then the conversion from \lstinline@T@ to type \lstinline@V@ is an \emph{indirect} safe arithmetic conversion. 255 261 256 262 \begin{rationale} … … 275 281 int x, y; 276 282 }; 277 void move_by( struct point * p1, struct point * p2 ) { @\impl{move_by}@283 void move_by( struct point * p1, struct point * p2 ) {§\impl{move_by}§ 278 284 p1->x += p2.x; 279 285 p1->y += p2.y; … … 285 291 move_to( &cp1, &cp2 ); 286 292 \end{lstlisting} 287 Thanks to implicit conversion, the two arguments that \lstinline $move_by()$receives are pointers to288 \lstinline $cp1$'s second member and \lstinline$cp2$'s second member.293 Thanks to implicit conversion, the two arguments that \lstinline@move_by()@ receives are pointers to 294 \lstinline@cp1@'s second member and \lstinline@cp2@'s second member. 289 295 290 296 … … 328 334 a direct safe arithmetic conversion; 329 335 \item 330 from any object type or incomplete type to \lstinline $void$;331 \item 332 from a pointer to any non-\lstinline $void$ type to a pointer to \lstinline$void$;336 from any object type or incomplete type to \lstinline@void@; 337 \item 338 from a pointer to any non-\lstinline@void@ type to a pointer to \lstinline@void@; 333 339 \item 334 340 from a pointer to any type to a pointer to a more qualified version of the type\index{qualified type}; … … 341 347 Conversions that are not safe conversions are \define{unsafe conversion}s. 342 348 \begin{rationale} 343 As in C, there is an implicit conversion from \lstinline $void *$to any pointer type.349 As in C, there is an implicit conversion from \lstinline@void *@ to any pointer type. 344 350 This is clearly dangerous, and {\CC} does not have this implicit conversion. 345 351 \CFA\index{deficiencies!void * conversion} keeps it, in the interest of remaining as pure a superset of C as possible, but discourages it by making it unsafe. … … 367 373 \begin{itemize} 368 374 \item 369 The cost of an implicit conversion from \lstinline $int$ to \lstinline$long$is 1.370 The cost of an implicit conversion from \lstinline $long$ to \lstinline$double$ is 3, because it is defined in terms of conversions from \lstinline$long$ to \lstinline$unsigned long$, then to \lstinline$float$, and then to \lstinline$double$.371 372 \item 373 If \lstinline $int$ can represent all the values of \lstinline$unsigned short$, then the cost of an implicit conversion from \lstinline$unsigned short$ to \lstinline$unsigned$is 2:374 \lstinline $unsigned short$ to \lstinline$int$ to \lstinline$unsigned$.375 Otherwise, \lstinline $unsigned short$ is converted directly to \lstinline$unsigned$, and the cost is 1.376 377 \item 378 If \lstinline $long$ can represent all the values of \lstinline$unsigned$, then the conversion cost of \lstinline$unsigned$ to \lstinline$long$is 1.375 The cost of an implicit conversion from \lstinline@int@ to \lstinline@long@ is 1. 376 The cost of an implicit conversion from \lstinline@long@ to \lstinline@double@ is 3, because it is defined in terms of conversions from \lstinline@long@ to \lstinline@unsigned long@, then to \lstinline@float@, and then to \lstinline@double@. 377 378 \item 379 If \lstinline@int@ can represent all the values of \lstinline@unsigned short@, then the cost of an implicit conversion from \lstinline@unsigned short@ to \lstinline@unsigned@ is 2: 380 \lstinline@unsigned short@ to \lstinline@int@ to \lstinline@unsigned@. 381 Otherwise, \lstinline@unsigned short@ is converted directly to \lstinline@unsigned@, and the cost is 1. 382 383 \item 384 If \lstinline@long@ can represent all the values of \lstinline@unsigned@, then the conversion cost of \lstinline@unsigned@ to \lstinline@long@ is 1. 379 385 Otherwise, the conversion is an unsafe conversion, and its conversion cost is undefined. 380 386 \end{itemize} … … 384 390 \begin{syntax} 385 391 \oldlhs{keyword} 386 \rhs \lstinline $forall$387 \rhs \lstinline $lvalue$388 \rhs \lstinline $trait$389 \rhs \lstinline $dtype$390 \rhs \lstinline $ftype$391 \rhs \lstinline $type$392 \rhs \lstinline@forall@ 393 \rhs \lstinline@lvalue@ 394 \rhs \lstinline@trait@ 395 \rhs \lstinline@dtype@ 396 \rhs \lstinline@ftype@ 397 \rhs \lstinline@otype@ 392 398 \end{syntax} 393 399 … … 396 402 397 403 \CFA allows operator \Index{overloading} by associating operators with special function identifiers. 398 Furthermore, the constants ``\lstinline $0$'' and ``\lstinline$1$'' have special status for many of C's data types (and for many programmer-defined data types as well), so \CFA treats them as overloadable identifiers.404 Furthermore, the constants ``\lstinline@0@'' and ``\lstinline@1@'' have special status for many of C's data types (and for many programmer-defined data types as well), so \CFA treats them as overloadable identifiers. 399 405 Programmers can use these identifiers to declare functions and objects that implement operators and constants for their own types. 400 406 … … 405 411 \begin{syntax} 406 412 \oldlhs{identifier} 407 \rhs \lstinline $0$408 \rhs \lstinline $1$413 \rhs \lstinline@0@ 414 \rhs \lstinline@1@ 409 415 \end{syntax} 410 416 411 \index{constant identifiers}\index{identifiers!for constants} The tokens ``\lstinline $0$''\impl{0} and ``\lstinline$1$''\impl{1} are identifiers.417 \index{constant identifiers}\index{identifiers!for constants} The tokens ``\lstinline@0@''\impl{0} and ``\lstinline@1@''\impl{1} are identifiers. 412 418 No other tokens defined by the rules for integer constants are considered to be identifiers. 413 419 \begin{rationale} 414 Why ``\lstinline $0$'' and ``\lstinline$1$''? Those integers have special status in C.420 Why ``\lstinline@0@'' and ``\lstinline@1@''? Those integers have special status in C. 415 421 All scalar types can be incremented and decremented, which is defined in terms of adding or subtracting 1. 416 The operations ``\lstinline $&&$'', ``\lstinline$||$'', and ``\lstinline$!$'' can be applied to any scalar arguments, and are defined in terms of comparison against 0.422 The operations ``\lstinline@&&@'', ``\lstinline@||@'', and ``\lstinline@!@'' can be applied to any scalar arguments, and are defined in terms of comparison against 0. 417 423 A \nonterm{constant-expression} that evaluates to 0 is effectively compatible with every pointer type. 418 424 419 425 In C, the integer constants 0 and 1 suffice because the integer promotion rules can convert them to any arithmetic type, and the rules for pointer expressions treat constant expressions evaluating to 0 as a special case. 420 426 However, user-defined arithmetic types often need the equivalent of a 1 or 0 for their functions or operators, polymorphic functions often need 0 and 1 constants of a type matching their polymorphic parameters, and user-defined pointer-like types may need a null value. 421 Defining special constants for a user-defined type is more efficient than defining a conversion to the type from \lstinline $_Bool$.422 423 Why \emph{just} ``\lstinline $0$'' and ``\lstinline$1$''? Why not other integers? No other integers have special status in C.424 A facility that let programmers declare specific constants---``\lstinline $const Rational 12$'', for instance---would not be much of an improvement.427 Defining special constants for a user-defined type is more efficient than defining a conversion to the type from \lstinline@_Bool@. 428 429 Why \emph{just} ``\lstinline@0@'' and ``\lstinline@1@''? Why not other integers? No other integers have special status in C. 430 A facility that let programmers declare specific constants---``\lstinline@const Rational 12@'', for instance---would not be much of an improvement. 425 431 Some facility for defining the creation of values of programmer-defined types from arbitrary integer tokens would be needed. 426 432 The complexity of such a feature doesn't seem worth the gain. … … 438 444 \begin{tabular}[t]{ll} 439 445 %identifier & operation \\ \hline 440 \lstinline $?[?]$& subscripting \impl{?[?]}\\441 \lstinline $?()$& function call \impl{?()}\\442 \lstinline $?++$& postfix increment \impl{?++}\\443 \lstinline $?--$& postfix decrement \impl{?--}\\444 \lstinline $++?$& prefix increment \impl{++?}\\445 \lstinline $--?$& prefix decrement \impl{--?}\\446 \lstinline $*?$& dereference \impl{*?}\\447 \lstinline $+?$& unary plus \impl{+?}\\448 \lstinline $-?$& arithmetic negation \impl{-?}\\449 \lstinline $~?$& bitwise negation \impl{~?}\\450 \lstinline $!?$& logical complement \impl{"!?}\\451 \lstinline $?*?$& multiplication \impl{?*?}\\452 \lstinline $?/?$& division \impl{?/?}\\446 \lstinline@?[?]@ & subscripting \impl{?[?]}\\ 447 \lstinline@?()@ & function call \impl{?()}\\ 448 \lstinline@?++@ & postfix increment \impl{?++}\\ 449 \lstinline@?--@ & postfix decrement \impl{?--}\\ 450 \lstinline@++?@ & prefix increment \impl{++?}\\ 451 \lstinline@--?@ & prefix decrement \impl{--?}\\ 452 \lstinline@*?@ & dereference \impl{*?}\\ 453 \lstinline@+?@ & unary plus \impl{+?}\\ 454 \lstinline@-?@ & arithmetic negation \impl{-?}\\ 455 \lstinline@~?@ & bitwise negation \impl{~?}\\ 456 \lstinline@!?@ & logical complement \impl{"!?}\\ 457 \lstinline@?*?@ & multiplication \impl{?*?}\\ 458 \lstinline@?/?@ & division \impl{?/?}\\ 453 459 \end{tabular}\hfil 454 460 \begin{tabular}[t]{ll} 455 461 %identifier & operation \\ \hline 456 \lstinline $?%?$& remainder \impl{?%?}\\457 \lstinline $?+?$& addition \impl{?+?}\\458 \lstinline $?-?$& subtraction \impl{?-?}\\459 \lstinline $?<<?$& left shift \impl{?<<?}\\460 \lstinline $?>>?$& right shift \impl{?>>?}\\461 \lstinline $?<?$& less than \impl{?<?}\\462 \lstinline $?<=?$& less than or equal \impl{?<=?}\\463 \lstinline $?>=?$& greater than or equal \impl{?>=?}\\464 \lstinline $?>?$& greater than \impl{?>?}\\465 \lstinline $?==?$& equality \impl{?==?}\\466 \lstinline $?!=?$& inequality \impl{?"!=?}\\467 \lstinline $?&?$& bitwise AND \impl{?&?}\\462 \lstinline@?%?@ & remainder \impl{?%?}\\ 463 \lstinline@?+?@ & addition \impl{?+?}\\ 464 \lstinline@?-?@ & subtraction \impl{?-?}\\ 465 \lstinline@?<<?@ & left shift \impl{?<<?}\\ 466 \lstinline@?>>?@ & right shift \impl{?>>?}\\ 467 \lstinline@?<?@ & less than \impl{?<?}\\ 468 \lstinline@?<=?@ & less than or equal \impl{?<=?}\\ 469 \lstinline@?>=?@ & greater than or equal \impl{?>=?}\\ 470 \lstinline@?>?@ & greater than \impl{?>?}\\ 471 \lstinline@?==?@ & equality \impl{?==?}\\ 472 \lstinline@?!=?@ & inequality \impl{?"!=?}\\ 473 \lstinline@?&?@ & bitwise AND \impl{?&?}\\ 468 474 \end{tabular}\hfil 469 475 \begin{tabular}[t]{ll} 470 476 %identifier & operation \\ \hline 471 \lstinline $?^?$& exclusive OR \impl{?^?}\\472 \lstinline $?|?$& inclusive OR \impl{?"|?}\\473 \lstinline $?=?$& simple assignment \impl{?=?}\\474 \lstinline $?*=?$& multiplication assignment \impl{?*=?}\\475 \lstinline $?/=?$& division assignment \impl{?/=?}\\476 \lstinline $?%=?$& remainder assignment \impl{?%=?}\\477 \lstinline $?+=?$& addition assignment \impl{?+=?}\\478 \lstinline $?-=?$& subtraction assignment \impl{?-=?}\\479 \lstinline $?<<=?$& left-shift assignment \impl{?<<=?}\\480 \lstinline $?>>=?$& right-shift assignment \impl{?>>=?}\\481 \lstinline $?&=?$& bitwise AND assignment \impl{?&=?}\\482 \lstinline $?^=?$& exclusive OR assignment \impl{?^=?}\\483 \lstinline $?|=?$& inclusive OR assignment \impl{?"|=?}\\477 \lstinline@?^?@ & exclusive OR \impl{?^?}\\ 478 \lstinline@?|?@ & inclusive OR \impl{?"|?}\\ 479 \lstinline@?=?@ & simple assignment \impl{?=?}\\ 480 \lstinline@?*=?@ & multiplication assignment \impl{?*=?}\\ 481 \lstinline@?/=?@ & division assignment \impl{?/=?}\\ 482 \lstinline@?%=?@ & remainder assignment \impl{?%=?}\\ 483 \lstinline@?+=?@ & addition assignment \impl{?+=?}\\ 484 \lstinline@?-=?@ & subtraction assignment \impl{?-=?}\\ 485 \lstinline@?<<=?@ & left-shift assignment \impl{?<<=?}\\ 486 \lstinline@?>>=?@ & right-shift assignment \impl{?>>=?}\\ 487 \lstinline@?&=?@ & bitwise AND assignment \impl{?&=?}\\ 488 \lstinline@?^=?@ & exclusive OR assignment \impl{?^=?}\\ 489 \lstinline@?|=?@ & inclusive OR assignment \impl{?"|=?}\\ 484 490 \end{tabular} 485 491 \hfil … … 496 502 497 503 \begin{rationale} 498 The use of ``\lstinline $?$'' in identifiers means that some C programs are not \CFA programs. For instance, the sequence of characters ``\lstinline$(i < 0)?--i:i$'' is legal in a C program, but a499 \CFA compiler detects a syntax error because it treats ``\lstinline $?--$'' as an identifier, not as the two tokens ``\lstinline$?$'' and ``\lstinline$--$''.504 The use of ``\lstinline@?@'' in identifiers means that some C programs are not \CFA programs. For instance, the sequence of characters ``\lstinline@(i < 0)?--i:i@'' is legal in a C program, but a 505 \CFA compiler detects a syntax error because it treats ``\lstinline@?--@'' as an identifier, not as the two tokens ``\lstinline@?@'' and ``\lstinline@--@''. 500 506 \end{rationale} 501 507 … … 504 510 \begin{itemize} 505 511 \item 506 The logical operators ``\lstinline $&&$'' and ``\lstinline$||$'', and the conditional operator507 ``\lstinline $?:$''.512 The logical operators ``\lstinline@&&@'' and ``\lstinline@||@'', and the conditional operator 513 ``\lstinline@?:@''. 508 514 These operators do not always evaluate their operands, and hence can not be properly defined by functions unless some mechanism like call-by-name is added to the language. 509 Note that the definitions of ``\lstinline $&&$'' and ``\lstinline$||$'' say that they work by checking that their arguments are unequal to 0, so defining ``\lstinline$!=$'' and ``\lstinline$0$'' for user-defined types is enough to allow them to be used in logical expressions.515 Note that the definitions of ``\lstinline@&&@'' and ``\lstinline@||@'' say that they work by checking that their arguments are unequal to 0, so defining ``\lstinline@!=@'' and ``\lstinline@0@'' for user-defined types is enough to allow them to be used in logical expressions. 510 516 511 517 \item … … 516 522 \item 517 523 The ``address of'' operator. 518 It would seem useful to define a unary ``\lstinline $&$'' operator that returns values of some programmer-defined pointer-like type.524 It would seem useful to define a unary ``\lstinline@&@'' operator that returns values of some programmer-defined pointer-like type. 519 525 The problem lies with the type of the operator. 520 Consider the expression ``\lstinline $p = &x$'', where \lstinline$x$is of type521 \lstinline $T$ and \lstinline$p$ has the programmer-defined type \lstinline$T_ptr$.522 The expression might be treated as a call to the unary function ``\lstinline $&?$''.523 Now what is the type of the function's parameter? It can not be \lstinline $T$, because then \lstinline$x$would be passed by value, and there is no way to create a useful pointer-like result from a value.524 Hence the parameter must have type \lstinline $T *$.525 But then the expression must be rewritten as ``\lstinline $p = &?( &x )$''526 Consider the expression ``\lstinline@p = &x@'', where \lstinline@x@ is of type 527 \lstinline@T@ and \lstinline@p@ has the programmer-defined type \lstinline@T_ptr@. 528 The expression might be treated as a call to the unary function ``\lstinline@&?@''. 529 Now what is the type of the function's parameter? It can not be \lstinline@T@, because then \lstinline@x@ would be passed by value, and there is no way to create a useful pointer-like result from a value. 530 Hence the parameter must have type \lstinline@T *@. 531 But then the expression must be rewritten as ``\lstinline@p = &?( &x )@'' 526 532 ---which doesn't seem like progress! 527 533 528 534 The rule for address-of expressions would have to be something like ``keep applying address-of functions until you get one that takes a pointer argument, then use the built-in operator and stop''. 529 It seems simpler to define a conversion function from \lstinline $T *$ to \lstinline$T_ptr$.530 531 \item 532 The \lstinline $sizeof$operator.535 It seems simpler to define a conversion function from \lstinline@T *@ to \lstinline@T_ptr@. 536 537 \item 538 The \lstinline@sizeof@ operator. 533 539 It is already defined for every object type, and intimately tied into the language's storage allocation model. 534 540 Redefining it seems pointless. 535 541 536 542 \item 537 The ``member of'' operators ``\lstinline $.$'' and ``\lstinline$->$''.543 The ``member of'' operators ``\lstinline@.@'' and ``\lstinline@->@''. 538 544 These are not really infix operators, since their right ``operand'' is not a value or object. 539 545 … … 572 578 The ``fewest unsafe conversions'' rule ensures that the usual conversions are done, if possible. 573 579 The ``lowest total expression cost'' rule chooses the proper common type. 574 The odd-looking ``highest argument conversion cost'' rule ensures that, when unary expressions must be converted, conversions of function results are preferred to conversion of function arguments: \lstinline $(double)-i$ will be preferred to \lstinline$-(double)i$.580 The odd-looking ``highest argument conversion cost'' rule ensures that, when unary expressions must be converted, conversions of function results are preferred to conversion of function arguments: \lstinline@(double)-i@ will be preferred to \lstinline@-(double)i@. 575 581 576 582 The ``least polymorphic'' rule reduces the number of polymorphic function calls, since such functions are presumably more expensive than monomorphic functions and since the more specific function is presumably more appropriate. 577 583 It also gives preference to monomorphic values (such as the 578 \lstinline $int$ \lstinline$0$) over polymorphic values (such as the \Index{null pointer}579 \lstinline $0$\use{0}).584 \lstinline@int@ \lstinline@0@) over polymorphic values (such as the \Index{null pointer} 585 \lstinline@0@\use{0}). 580 586 However, interpretations that call polymorphic functions are preferred to interpretations that perform unsafe conversions, because those conversions potentially lose accuracy or violate strong typing. 581 587 … … 597 603 \begin{rationale} 598 604 Predefined functions and constants have internal linkage because that simplifies optimization in traditional compile-and-link environments. 599 For instance, ``\lstinline $an_int + an_int$'' is equivalent to ``\lstinline$?+?(an_int, an_int)$''.605 For instance, ``\lstinline@an_int + an_int@'' is equivalent to ``\lstinline@?+?(an_int, an_int)@''. 600 606 If integer addition has not been redefined in the current scope, a compiler can generate code to perform the addition directly. 601 607 If predefined functions had external linkage, this optimization would be difficult. … … 623 629 \rhs \nonterm{constant} 624 630 \rhs \nonterm{string-literal} 625 \rhs \lstinline $($ \nonterm{expression} \lstinline$)$631 \rhs \lstinline@(@ \nonterm{expression} \lstinline@)@ 626 632 \rhs \nonterm{generic-selection} 627 633 \end{syntax} … … 629 635 \predefined 630 636 \begin{lstlisting} 631 const int 1; @\use{1}@632 const int 0; @\use{0}@637 const int 1;§\use{1}§ 638 const int 0;§\use{0}§ 633 639 forall( dtype DT ) DT * const 0; 634 640 forall( ftype FT ) FT * const 0; … … 639 645 640 646 A \nonterm{constant} or \nonterm{string-literal} has one valid interpretation, which has the type and value defined by {\c11}. 641 The predefined integer identifiers ``\lstinline $1$'' and ``\lstinline$0$'' have the integer values 1 and 0, respectively.642 The other two predefined ``\lstinline $0$'' identifiers are bound to polymorphic pointer values that, when specialized\index{specialization} with a data type or function type respectively, produce a null pointer of that type.647 The predefined integer identifiers ``\lstinline@1@'' and ``\lstinline@0@'' have the integer values 1 and 0, respectively. 648 The other two predefined ``\lstinline@0@'' identifiers are bound to polymorphic pointer values that, when specialized\index{specialization} with a data type or function type respectively, produce a null pointer of that type. 643 649 644 650 A parenthesised expression has the same interpretations as the contained \nonterm{expression}. 645 651 646 652 \examples 647 The expression \lstinline $(void *)0$\use{0} specializes the (polymorphic) null pointer to a null pointer to \lstinline$void$. \lstinline$(const void *)0$ does the same, and also uses a safe conversion from \lstinline$void *$ to \lstinline$const void *$.653 The expression \lstinline@(void *)0@\use{0} specializes the (polymorphic) null pointer to a null pointer to \lstinline@void@. \lstinline@(const void *)0@ does the same, and also uses a safe conversion from \lstinline@void *@ to \lstinline@const void *@. 648 654 In each case, the null pointer conversion is better\index{best valid interpretations} than the unsafe conversion of the integer 649 \lstinline $0$to a pointer.655 \lstinline@0@ to a pointer. 650 656 651 657 \begin{rationale} … … 653 659 654 660 \CFA does not have C's concept of ``null pointer constants'', which are not typed values but special strings of tokens. 655 The C token ``\lstinline $0$'' is an expression of type \lstinline$int$with the value ``zero'', and it \emph{also} is a null pointer constant.661 The C token ``\lstinline@0@'' is an expression of type \lstinline@int@ with the value ``zero'', and it \emph{also} is a null pointer constant. 656 662 Similarly, 657 ``\lstinline $(void *)0$ is an expression of type \lstinline$(void *)$whose value is a null pointer, and it also is a null pointer constant.658 However, in C, ``\lstinline $(void *)(void *)0$'' is663 ``\lstinline@(void *)0@ is an expression of type \lstinline@(void *)@ whose value is a null pointer, and it also is a null pointer constant. 664 However, in C, ``\lstinline@(void *)(void *)0@'' is 659 665 \emph{not} a null pointer constant, even though it is null-valued, a pointer, and constant! The semantics of C expressions contain many special cases to deal with subexpressions that are null pointer constants. 660 666 … … 663 669 \begin{lstlisting} 664 670 forall( dtype DT ) DT * const 0; 665 \end{lstlisting} means that \lstinline $0$is a polymorphic object, and contains a value that can have \emph{any} pointer-to-object type or pointer-to-incomplete type.671 \end{lstlisting} means that \lstinline@0@ is a polymorphic object, and contains a value that can have \emph{any} pointer-to-object type or pointer-to-incomplete type. 666 672 The only such value is the null pointer. 667 673 Therefore the type \emph{alone} is enough to identify a null pointer. … … 673 679 674 680 \constraints The best interpretation of the controlling expression shall be unambiguous\index{ambiguous interpretation}, and shall have type compatible with at most one of the types named in its generic association list. 675 If a generic selection has no \lstinline $default$generic association, the best interpretation of its controlling expression shall have type compatible with exactly one of the types named in its generic association list.681 If a generic selection has no \lstinline@default@ generic association, the best interpretation of its controlling expression shall have type compatible with exactly one of the types named in its generic association list. 676 682 677 683 \semantics … … 684 690 \lhs{postfix-expression} 685 691 \rhs \nonterm{primary-expression} 686 \rhs \nonterm{postfix-expression} \lstinline $[$ \nonterm{expression} \lstinline$]$687 \rhs \nonterm{postfix-expression} \lstinline $($688 \nonterm{argument-expression-list}\opt \lstinline $)$689 \rhs \nonterm{postfix-expression} \lstinline $.$\nonterm{identifier}690 \rhs \nonterm{postfix-expression} \lstinline $->$\nonterm{identifier}691 \rhs \nonterm{postfix-expression} \lstinline $++$692 \rhs \nonterm{postfix-expression} \lstinline $--$693 \rhs \lstinline $($ \nonterm{type-name} \lstinline$)$ \lstinline${$ \nonterm{initializer-list} \lstinline$}$694 \rhs \lstinline $($ \nonterm{type-name} \lstinline$)$ \lstinline${$ \nonterm{initializer-list} \lstinline$,$ \lstinline$}$692 \rhs \nonterm{postfix-expression} \lstinline@[@ \nonterm{expression} \lstinline@]@ 693 \rhs \nonterm{postfix-expression} \lstinline@(@ 694 \nonterm{argument-expression-list}\opt \lstinline@)@ 695 \rhs \nonterm{postfix-expression} \lstinline@.@ \nonterm{identifier} 696 \rhs \nonterm{postfix-expression} \lstinline@->@ \nonterm{identifier} 697 \rhs \nonterm{postfix-expression} \lstinline@++@ 698 \rhs \nonterm{postfix-expression} \lstinline@--@ 699 \rhs \lstinline@(@ \nonterm{type-name} \lstinline@)@ \lstinline@{@ \nonterm{initializer-list} \lstinline@}@ 700 \rhs \lstinline@(@ \nonterm{type-name} \lstinline@)@ \lstinline@{@ \nonterm{initializer-list} \lstinline@,@ \lstinline@}@ 695 701 \lhs{argument-expression-list} 696 702 \rhs \nonterm{assignment-expression} 697 \rhs \nonterm{argument-expression-list} \lstinline $,$703 \rhs \nonterm{argument-expression-list} \lstinline@,@ 698 704 \nonterm{assignment-expression} 699 705 \end{syntax} … … 701 707 \rewriterules 702 708 \begin{lstlisting} 703 a[b] @\rewrite@ ?[?]( b, a ) // if a has integer type@\use{?[?]}@704 a[b] @\rewrite@?[?]( a, b ) // otherwise705 a( @\emph{arguments}@ ) @\rewrite@ ?()( a, @\emph{arguments}@ )@\use{?()}@706 a++ @\rewrite@ ?++(&( a ))@\use{?++}@707 a-- @\rewrite@ ?--(&( a ))@\use{?--}@709 a[b] §\rewrite§ ?[?]( b, a ) // if a has integer type§\use{?[?]}§ 710 a[b] §\rewrite§ ?[?]( a, b ) // otherwise 711 a( §\emph{arguments}§ ) §\rewrite§ ?()( a, §\emph{arguments}§ )§\use{?()}§ 712 a++ §\rewrite§ ?++(&( a ))§\use{?++}§ 713 a-- §\rewrite§ ?--(&( a ))§\use{?--}§ 708 714 \end{lstlisting} 709 715 … … 713 719 \predefined 714 720 \begin{lstlisting} 715 forall( otype T ) lvalue T ?[?]( T *, ptrdiff_t ); @\use{ptrdiff_t}@721 forall( otype T ) lvalue T ?[?]( T *, ptrdiff_t );§\use{ptrdiff_t}§ 716 722 forall( otype T ) lvalue _Atomic T ?[?]( _Atomic T *, ptrdiff_t ); 717 723 forall( otype T ) lvalue const T ?[?]( const T *, ptrdiff_t ); … … 733 739 The interpretations of subscript expressions are the interpretations of the corresponding function call expressions. 734 740 \begin{rationale} 735 C defines subscripting as pointer arithmetic in a way that makes \lstinline $a[i]$and736 \lstinline $i[a]$ equivalent. \CFA provides the equivalence through a rewrite rule to reduce the number of overloadings of \lstinline$?[?]$.741 C defines subscripting as pointer arithmetic in a way that makes \lstinline@a[i]@ and 742 \lstinline@i[a]@ equivalent. \CFA provides the equivalence through a rewrite rule to reduce the number of overloadings of \lstinline@?[?]@. 737 743 738 744 Subscript expressions are rewritten as function calls that pass the first parameter by value. 739 745 This is somewhat unfortunate, since array-like types tend to be large. 740 The alternative is to use the rewrite rule ``\lstinline $a[b]$ \rewrite \lstinline$?[?](&(a), b)$''.741 However, C semantics forbid this approach: the \lstinline $a$ in ``\lstinline$a[b]$'' can be an arbitrary pointer value, which does not have an address.746 The alternative is to use the rewrite rule ``\lstinline@a[b]@ \rewrite \lstinline@?[?](&(a), b)@''. 747 However, C semantics forbid this approach: the \lstinline@a@ in ``\lstinline@a[b]@'' can be an arbitrary pointer value, which does not have an address. 742 748 743 749 The repetitive form of the predefined identifiers shows up a deficiency\index{deficiencies!pointers … … 754 760 \nonterm{postfix-expression} in a function call may have some interpretations that are function designators and some that are not. 755 761 756 For those interpretations of the \nonterm{postfix-expression} that are not function designators, the expression is rewritten and becomes a call of a function named ``\lstinline $?()$''.762 For those interpretations of the \nonterm{postfix-expression} that are not function designators, the expression is rewritten and becomes a call of a function named ``\lstinline@?()@''. 757 763 The valid interpretations of the rewritten expression are determined in the manner described below. 758 764 … … 762 768 \item if the argument corresponds to a parameter in the function designator's prototype, the argument interpretation must have the same type as the corresponding parameter, or be implicitly convertible to the parameter's type 763 769 \item if the function designator's type does not include a prototype or if the argument corresponds to 764 ``\lstinline $...$'' in a prototype, a \Index{default argument promotion} is applied to it.770 ``\lstinline@...@'' in a prototype, a \Index{default argument promotion} is applied to it. 765 771 \end{itemize} 766 772 The type of the valid interpretation is the return type of the function designator. … … 770 776 \begin{itemize} 771 777 \item 772 If the declaration of the implicit parameter uses \Index{type-class} \lstinline $type$\use{type}, the implicit argument must be an object type;773 if it uses \lstinline $dtype$, the implicit argument must be an object type or an incomplete type;774 and if it uses \lstinline $ftype$, the implicit argument must be a function type.778 If the declaration of the implicit parameter uses \Index{type-class} \lstinline@type@\use{type}, the implicit argument must be an object type; 779 if it uses \lstinline@dtype@, the implicit argument must be an object type or an incomplete type; 780 and if it uses \lstinline@ftype@, the implicit argument must be a function type. 775 781 776 782 \item if an explicit parameter's type uses any implicit parameters, then the corresponding explicit argument must have a type that is (or can be safely converted\index{safe conversion} to) the type produced by substituting the implicit arguments for the implicit parameters in the explicit parameter type. … … 791 797 \begin{rationale} 792 798 One desirable property of a polymorphic programming language is \define{generalizability}: the ability to replace an abstraction with a more general but equivalent abstraction without requiring changes in any of the uses of the original\cite{Cormack90}. 793 For instance, it should be possible to replace a function ``\lstinline $int f( int );$'' with ``\lstinline$forall( otype T ) T f( T );$'' without affecting any calls of \lstinline$f$.799 For instance, it should be possible to replace a function ``\lstinline@int f( int );@'' with ``\lstinline@forall( otype T ) T f( T );@'' without affecting any calls of \lstinline@f@. 794 800 795 801 \CFA\index{deficiencies!generalizability} does not fully possess this property, because … … 805 811 f = g( d, f ); // (3) (unsafe conversion to float) 806 812 \end{lstlisting} 807 If \lstinline $g$ was replaced by ``\lstinline$forall( otype T ) T g( T, T );$'', the first and second calls would be unaffected, but the third would change: \lstinline$f$would be converted to808 \lstinline $double$, and the result would be a \lstinline$double$.809 810 Another example is the function ``\lstinline $void h( int *);$''.813 If \lstinline@g@ was replaced by ``\lstinline@forall( otype T ) T g( T, T );@'', the first and second calls would be unaffected, but the third would change: \lstinline@f@ would be converted to 814 \lstinline@double@, and the result would be a \lstinline@double@. 815 816 Another example is the function ``\lstinline@void h( int *);@''. 811 817 This function can be passed a 812 \lstinline $void *$ argument, but the generalization ``\lstinline$forall( otype T ) void h( T *);$'' can not.813 In this case, \lstinline $void$ is not a valid value for \lstinline$T$because it is not an object type.814 If unsafe conversions were allowed, \lstinline $T$could be inferred to be \emph{any} object type, which is undesirable.818 \lstinline@void *@ argument, but the generalization ``\lstinline@forall( otype T ) void h( T *);@'' can not. 819 In this case, \lstinline@void@ is not a valid value for \lstinline@T@ because it is not an object type. 820 If unsafe conversions were allowed, \lstinline@T@ could be inferred to be \emph{any} object type, which is undesirable. 815 821 \end{rationale} 816 822 817 823 \examples 818 A function called ``\lstinline $?()$'' might be part of a numerical differentiation package.824 A function called ``\lstinline@?()@'' might be part of a numerical differentiation package. 819 825 \begin{lstlisting} 820 826 extern otype Derivative; … … 827 833 d = sin_dx( 12.9 ); 828 834 \end{lstlisting} 829 Here, the only interpretation of \lstinline $sin_dx$ is as an object of type \lstinline$Derivative$.830 For that interpretation, the function call is treated as ``\lstinline $?()( sin_dx, 12.9 )$''.835 Here, the only interpretation of \lstinline@sin_dx@ is as an object of type \lstinline@Derivative@. 836 For that interpretation, the function call is treated as ``\lstinline@?()( sin_dx, 12.9 )@''. 831 837 \begin{lstlisting} 832 838 int f( long ); // (1) … … 835 841 int i = f( 5 ); // calls (1) 836 842 \end{lstlisting} 837 Function (1) provides a valid interpretation of ``\lstinline $f( 5 )$'', using an implicit \lstinline$int$ to \lstinline$long$conversion.838 The other functions do not, since the second requires two arguments, and since there is no implicit conversion from \lstinline $int$ to \lstinline$int *$that could be used with the third function.843 Function (1) provides a valid interpretation of ``\lstinline@f( 5 )@'', using an implicit \lstinline@int@ to \lstinline@long@ conversion. 844 The other functions do not, since the second requires two arguments, and since there is no implicit conversion from \lstinline@int@ to \lstinline@int *@ that could be used with the third function. 839 845 840 846 \begin{lstlisting} … … 842 848 double d = h( 1.5 ); 843 849 \end{lstlisting} 844 ``\lstinline $1.5$'' is a \lstinline$double$ constant, so \lstinline$T$is inferred to be845 \lstinline $double$, and the result of the function call is a \lstinline$double$.850 ``\lstinline@1.5@'' is a \lstinline@double@ constant, so \lstinline@T@ is inferred to be 851 \lstinline@double@, and the result of the function call is a \lstinline@double@. 846 852 847 853 \begin{lstlisting} … … 858 864 g( i, p ); // calls (4) 859 865 \end{lstlisting} 860 The first call has valid interpretations for all four versions of \lstinline $g$. (6) and (7) are discarded because they involve unsafe \lstinline$double$-to-\lstinline$long$conversions. (5) is chosen because it is less polymorphic than (4).866 The first call has valid interpretations for all four versions of \lstinline@g@. (6) and (7) are discarded because they involve unsafe \lstinline@double@-to-\lstinline@long@ conversions. (5) is chosen because it is less polymorphic than (4). 861 867 862 868 For the second call, (7) is again discarded. 863 Of the remaining interpretations for (4), (5), and (6) (with \lstinline $i$ converted to \lstinline$long$), (6) is chosen because it is the least polymorphic.869 Of the remaining interpretations for (4), (5), and (6) (with \lstinline@i@ converted to \lstinline@long@), (6) is chosen because it is the least polymorphic. 864 870 865 871 The third call has valid interpretations for all of the functions; … … 870 876 forall( otype T ) T min( T, T ); 871 877 double max( double, double ); 872 trait min_max( T ) { @\impl{min_max}@878 trait min_max( T ) {§\impl{min_max}§ 873 879 T min( T, T ); 874 880 T max( T, T ); … … 877 883 shuffle( 9, 10 ); 878 884 \end{lstlisting} 879 The only possibility for \lstinline $U$ is \lstinline$double$, because that is the type used in the only visible \lstinline$max$ function. 9 and 10 must be converted to \lstinline$double$, and880 \lstinline $min$ must be specialized with \lstinline$T$ bound to \lstinline$double$.885 The only possibility for \lstinline@U@ is \lstinline@double@, because that is the type used in the only visible \lstinline@max@ function. 9 and 10 must be converted to \lstinline@double@, and 886 \lstinline@min@ must be specialized with \lstinline@T@ bound to \lstinline@double@. 881 887 \begin{lstlisting} 882 888 extern void q( int ); // (8) … … 886 892 r( 0 ); 887 893 \end{lstlisting} 888 The \lstinline $int 0$ could be passed to (8), or the \lstinline$(void *)$ \Index{specialization} of the null pointer\index{null pointer} \lstinline$0$\use{0} could be passed to (9).889 The former is chosen because the \lstinline $int$ \lstinline$0$is \Index{less polymorphic}.890 For the same reason, \lstinline $int$ \lstinline$0$ is passed to \lstinline$r()$, even though it has \emph{no} declared parameter types.894 The \lstinline@int 0@ could be passed to (8), or the \lstinline@(void *)@ \Index{specialization} of the null pointer\index{null pointer} \lstinline@0@\use{0} could be passed to (9). 895 The former is chosen because the \lstinline@int@ \lstinline@0@ is \Index{less polymorphic}. 896 For the same reason, \lstinline@int@ \lstinline@0@ is passed to \lstinline@r()@, even though it has \emph{no} declared parameter types. 891 897 892 898 893 899 \subsubsection{Structure and union members} 894 900 895 \semantics In the member selection expression ``\lstinline $s$.\lstinline$m$'', there shall be at least one interpretation of \lstinline$s$ whose type is a structure type or union type containing a member named \lstinline$m$.896 If two or more interpretations of \lstinline $s$have members named897 \lstinline $m$with mutually compatible types, then the expression has an \Index{ambiguous interpretation} whose type is the composite type of the types of the members.898 If an interpretation of \lstinline $s$ has a member \lstinline$m$whose type is not compatible with any other899 \lstinline $s$'s \lstinline$m$, then the expression has an interpretation with the member's type.901 \semantics In the member selection expression ``\lstinline@s@.\lstinline@m@'', there shall be at least one interpretation of \lstinline@s@ whose type is a structure type or union type containing a member named \lstinline@m@. 902 If two or more interpretations of \lstinline@s@ have members named 903 \lstinline@m@ with mutually compatible types, then the expression has an \Index{ambiguous interpretation} whose type is the composite type of the types of the members. 904 If an interpretation of \lstinline@s@ has a member \lstinline@m@ whose type is not compatible with any other 905 \lstinline@s@'s \lstinline@m@, then the expression has an interpretation with the member's type. 900 906 The expression has no other interpretations. 901 907 902 The expression ``\lstinline$p->m$'' has the same interpretations as the expression 903 ``\lstinline$(*p).m$''. 908 The expression ``\lstinline@p->m@'' has the same interpretations as the expression ``\lstinline@(*p).m@''. 904 909 905 910 … … 996 1001 * ?--( _Atomic const restrict volatile T * _Atomic restrict volatile * ); 997 1002 \end{lstlisting} 998 For every extended integer type \lstinline $X$there exist1003 For every extended integer type \lstinline@X@ there exist 999 1004 % Don't use predefined: keep this out of prelude.cf. 1000 1005 \begin{lstlisting} … … 1002 1007 ?--( volatile X * ), ?--( _Atomic volatile X * ); 1003 1008 \end{lstlisting} 1004 For every complete enumerated type \lstinline $E$there exist1009 For every complete enumerated type \lstinline@E@ there exist 1005 1010 % Don't use predefined: keep this out of prelude.cf. 1006 1011 \begin{lstlisting} … … 1010 1015 1011 1016 \begin{rationale} 1012 Note that ``\lstinline $++$'' and ``\lstinline$--$'' are rewritten as function calls that are given a pointer to that operand. (This is true of all operators that modify an operand.) As Hamish Macdonald has pointed out, this forces the modified operand of such expressions to be an lvalue.1017 Note that ``\lstinline@++@'' and ``\lstinline@--@'' are rewritten as function calls that are given a pointer to that operand. (This is true of all operators that modify an operand.) As Hamish Macdonald has pointed out, this forces the modified operand of such expressions to be an lvalue. 1013 1018 This partially enforces the C semantic rule that such operands must be \emph{modifiable} lvalues. 1014 1019 \end{rationale} … … 1016 1021 \begin{rationale} 1017 1022 In C, a semantic rule requires that pointer operands of increment and decrement be pointers to object types. 1018 Hence, \lstinline $void *$objects cannot be incremented.1019 In \CFA, the restriction follows from the use of a \lstinline $type$ parameter in the predefined function definitions, as opposed to \lstinline$dtype$, since only object types can be inferred arguments corresponding to the type parameter \lstinline$T$.1023 Hence, \lstinline@void *@ objects cannot be incremented. 1024 In \CFA, the restriction follows from the use of a \lstinline@type@ parameter in the predefined function definitions, as opposed to \lstinline@dtype@, since only object types can be inferred arguments corresponding to the type parameter \lstinline@T@. 1020 1025 \end{rationale} 1021 1026 1022 1027 \semantics 1023 1028 First, each interpretation of the operand of an increment or decrement expression is considered separately. 1024 For each interpretation that is a bit-field or is declared with the 1025 \lstinline$register$\index{register@{\lstinline$register$}} \index{Itorage-class specifier}, the expression has one valid interpretation, with the type of the operand, and the expression is ambiguous if the operand is. 1029 For each interpretation that is a bit-field or is declared with the \Indexc{register}\index{storage-class specifier}, the expression has one valid interpretation, with the type of the operand, and the expression is ambiguous if the operand is. 1026 1030 1027 1031 For the remaining interpretations, the expression is rewritten, and the interpretations of the expression are the interpretations of the corresponding function call. … … 1036 1040 \end{lstlisting} 1037 1041 \begin{sloppypar} 1038 Since \lstinline$&(vs)$ has type \lstinline$volatile short int *$, the best valid interpretation of 1039 \lstinline$vs++$ calls the \lstinline$?++$ function with the \lstinline$volatile short *$ parameter. 1040 \lstinline$s++$ does the same, applying the safe conversion from \lstinline$short int *$ to 1041 \lstinline$volatile short int *$. 1042 Note that there is no conversion that adds an \lstinline$_Atomic$ qualifier, so the \lstinline$_Atomic volatile short int$ overloading does not provide a valid interpretation. 1042 Since \lstinline@&(vs)@ has type \lstinline@volatile short int *@, the best valid interpretation of 1043 \lstinline@vs++@ calls the \lstinline@?++@ function with the \lstinline@volatile short *@ parameter. 1044 \lstinline@s++@ does the same, applying the safe conversion from \lstinline@short int *@ to \lstinline@volatile short int *@. 1045 Note that there is no conversion that adds an \lstinline@_Atomic@ qualifier, so the \lstinline@_Atomic volatile short int@ overloading does not provide a valid interpretation. 1043 1046 \end{sloppypar} 1044 1047 1045 There is no safe conversion from \lstinline $const short int *$ to \lstinline$volatile short int *$, and no \lstinline$?++$ function that accepts a \lstinline$const *$ parameter, so \lstinline$cs++$has no valid interpretations.1046 1047 The best valid interpretation of \lstinline $as++$ calls the \lstinline$short ?++$ function with the \lstinline$_Atomic volatile short int *$ parameter, applying a safe conversion to add the \lstinline$volatile$qualifier.1048 There is no safe conversion from \lstinline@const short int *@ to \lstinline@volatile short int *@, and no \lstinline@?++@ function that accepts a \lstinline@const *@ parameter, so \lstinline@cs++@ has no valid interpretations. 1049 1050 The best valid interpretation of \lstinline@as++@ calls the \lstinline@short ?++@ function with the \lstinline@_Atomic volatile short int *@ parameter, applying a safe conversion to add the \lstinline@volatile@ qualifier. 1048 1051 \begin{lstlisting} 1049 1052 char * const restrict volatile * restrict volatile pqpc; … … 1052 1055 ppc++; 1053 1056 \end{lstlisting} 1054 Since \lstinline $&(pqpc)$ has type \lstinline$char * const restrict volatile * restrict volatile *$, the best valid interpretation of \lstinline$pqpc++$ calls the polymorphic \lstinline$?++$ function with the \lstinline$const restrict volatile T * restrict volatile *$ parameter, inferring \lstinline$T$ to be \lstinline$char *$.1055 1056 \lstinline $ppc++$ calls the same function, again inferring \lstinline$T$ to be \lstinline$char *$, and using the safe conversions from \lstinline$T$ to \lstinline$T const$ \lstinline$restrict volatile$.1057 Since \lstinline@&(pqpc)@ has type \lstinline@char * const restrict volatile * restrict volatile *@, the best valid interpretation of \lstinline@pqpc++@ calls the polymorphic \lstinline@?++@ function with the \lstinline@const restrict volatile T * restrict volatile *@ parameter, inferring \lstinline@T@ to be \lstinline@char *@. 1058 1059 \lstinline@ppc++@ calls the same function, again inferring \lstinline@T@ to be \lstinline@char *@, and using the safe conversions from \lstinline@T@ to \lstinline@T const@ \lstinline@restrict volatile@. 1057 1060 1058 1061 \begin{rationale} … … 1068 1071 \begin{enumerate} 1069 1072 \item 1070 ``\lstinline $char * p; p++;$''.1071 The argument to \lstinline $?++$ has type \lstinline$char * *$, and the result has type \lstinline$char *$.1072 The expression would be valid if \lstinline $?++$were declared by1073 ``\lstinline@char * p; p++;@''. 1074 The argument to \lstinline@?++@ has type \lstinline@char * *@, and the result has type \lstinline@char *@. 1075 The expression would be valid if \lstinline@?++@ were declared by 1073 1076 \begin{lstlisting} 1074 1077 forall( otype T ) T * ?++( T * * ); 1075 \end{lstlisting} with \lstinline $T$ inferred to be \lstinline$char$.1076 1077 \item 1078 ``\lstinline $char *restrict volatile qp; qp++$''.1079 The result again has type \lstinline $char *$, but the argument now has type \lstinline$char *restrict volatile *$, so it cannot be passed to the hypothetical function declared in point 1.1078 \end{lstlisting} with \lstinline@T@ inferred to be \lstinline@char@. 1079 1080 \item 1081 ``\lstinline@char *restrict volatile qp; qp++@''. 1082 The result again has type \lstinline@char *@, but the argument now has type \lstinline@char *restrict volatile *@, so it cannot be passed to the hypothetical function declared in point 1. 1080 1083 Hence the actual predefined function is 1081 1084 \begin{lstlisting} 1082 1085 forall( otype T ) T * ?++( T * restrict volatile * ); 1083 \end{lstlisting} which also accepts a \lstinline $char * *$argument, because of the safe conversions that add1084 \lstinline $volatile$ and \lstinline$restrict$qualifiers. (The parameter is not const-qualified, so constant pointers cannot be incremented.)1085 1086 \item 1087 ``\lstinline $char *_Atomic ap; ap++$''.1088 The result again has type \lstinline $char *$, but no safe conversion adds an \lstinline$_Atomic$qualifier, so the function in point 2 is not applicable.1089 A separate overloading of \lstinline $?++$is required.1090 1091 \item 1092 ``\lstinline $char const volatile * pq; pq++$''.1086 \end{lstlisting} which also accepts a \lstinline@char * *@ argument, because of the safe conversions that add 1087 \lstinline@volatile@ and \lstinline@restrict@ qualifiers. (The parameter is not const-qualified, so constant pointers cannot be incremented.) 1088 1089 \item 1090 ``\lstinline@char *_Atomic ap; ap++@''. 1091 The result again has type \lstinline@char *@, but no safe conversion adds an \lstinline@_Atomic@ qualifier, so the function in point 2 is not applicable. 1092 A separate overloading of \lstinline@?++@ is required. 1093 1094 \item 1095 ``\lstinline@char const volatile * pq; pq++@''. 1093 1096 Here the result has type 1094 \lstinline $char const volatile *$, so a new overloading is needed:1097 \lstinline@char const volatile *@, so a new overloading is needed: 1095 1098 \begin{lstlisting} 1096 1099 forall( otype T ) T const volatile * ?++( T const volatile *restrict volatile * ); … … 1099 1102 1100 1103 \item 1101 ``\lstinline $float *restrict * prp; prp++$''.1102 The \lstinline $restrict$ qualifier is handled just like \lstinline$const$ and \lstinline$volatile$in the previous case:1104 ``\lstinline@float *restrict * prp; prp++@''. 1105 The \lstinline@restrict@ qualifier is handled just like \lstinline@const@ and \lstinline@volatile@ in the previous case: 1103 1106 \begin{lstlisting} 1104 1107 forall( otype T ) T restrict * ?++( T restrict *restrict volatile * ); 1105 \end{lstlisting} with \lstinline $T$ inferred to be \lstinline$float *$.1106 This looks odd, because {\c11} contains a constraint that requires restrict-qualified types to be pointer-to-object types, and \lstinline $T$is not syntactically a pointer type. \CFA loosens the constraint.1108 \end{lstlisting} with \lstinline@T@ inferred to be \lstinline@float *@. 1109 This looks odd, because {\c11} contains a constraint that requires restrict-qualified types to be pointer-to-object types, and \lstinline@T@ is not syntactically a pointer type. \CFA loosens the constraint. 1107 1110 \end{enumerate} 1108 1111 \end{rationale} … … 1120 1123 \lhs{unary-expression} 1121 1124 \rhs \nonterm{postfix-expression} 1122 \rhs \lstinline $++$\nonterm{unary-expression}1123 \rhs \lstinline $--$\nonterm{unary-expression}1125 \rhs \lstinline@++@ \nonterm{unary-expression} 1126 \rhs \lstinline@--@ \nonterm{unary-expression} 1124 1127 \rhs \nonterm{unary-operator} \nonterm{cast-expression} 1125 \rhs \lstinline $sizeof$\nonterm{unary-expression}1126 \rhs \lstinline $sizeof$ \lstinline$($ \nonterm{type-name} \lstinline$)$1127 \lhs{unary-operator} one of \rhs \lstinline $&$ \lstinline$*$ \lstinline$+$ \lstinline$-$ \lstinline$~$ \lstinline$!$1128 \rhs \lstinline@sizeof@ \nonterm{unary-expression} 1129 \rhs \lstinline@sizeof@ \lstinline@(@ \nonterm{type-name} \lstinline@)@ 1130 \lhs{unary-operator} one of \rhs \lstinline@&@ \lstinline@*@ \lstinline@+@ \lstinline@-@ \lstinline@~@ \lstinline@!@ 1128 1131 \end{syntax} 1129 1132 1130 1133 \rewriterules 1131 1134 \begin{lstlisting} 1132 *a @\rewrite@ *?( a ) @\use{*?}@1133 +a @\rewrite@ +?( a ) @\use{+?}@1134 -a @\rewrite@ -?( a ) @\use{-?}@1135 ~a @\rewrite@ ~?( a ) @\use{~?}@1136 !a @\rewrite@ !?( a ) @\use{"!?}@1137 ++a @\rewrite@ ++?(&( a )) @\use{++?}@1138 --a @\rewrite@ --?(&( a )) @\use{--?}@1135 *a §\rewrite§ *?( a ) §\use{*?}§ 1136 +a §\rewrite§ +?( a ) §\use{+?}§ 1137 -a §\rewrite§ -?( a ) §\use{-?}§ 1138 ~a §\rewrite§ ~?( a ) §\use{~?}§ 1139 !a §\rewrite§ !?( a ) §\use{"!?}§ 1140 ++a §\rewrite§ ++?(&( a )) §\use{++?}§ 1141 --a §\rewrite§ --?(&( a )) §\use{--?}§ 1139 1142 \end{lstlisting} 1140 1143 … … 1232 1235 * --?( _Atomic const restrict volatile T * _Atomic restrict volatile * ); 1233 1236 \end{lstlisting} 1234 For every extended integer type \lstinline $X$there exist1237 For every extended integer type \lstinline@X@ there exist 1235 1238 % Don't use predefined: keep this out of prelude.cf. 1236 1239 \begin{lstlisting} … … 1240 1243 --?( _Atomic volatile X * ); 1241 1244 \end{lstlisting} 1242 For every complete enumerated type \lstinline $E$there exist1245 For every complete enumerated type \lstinline@E@ there exist 1243 1246 % Don't use predefined: keep this out of prelude.cf. 1244 1247 \begin{lstlisting} … … 1277 1280 1278 1281 \constraints 1279 The operand of the unary ``\lstinline $&$'' operator shall have exactly one1282 The operand of the unary ``\lstinline@&@'' operator shall have exactly one 1280 1283 \Index{interpretation}\index{ambiguous interpretation}, which shall be unambiguous. 1281 1284 1282 1285 \semantics 1283 The ``\lstinline $&$'' expression has one interpretation which is of type \lstinline$T *$, where1284 \lstinline $T$is the type of the operand.1286 The ``\lstinline@&@'' expression has one interpretation which is of type \lstinline@T *@, where 1287 \lstinline@T@ is the type of the operand. 1285 1288 1286 1289 The interpretations of an indirection expression are the interpretations of the corresponding function call. … … 1311 1314 forall( ftype FT ) int !?( FT * ); 1312 1315 \end{lstlisting} 1313 For every extended integer type \lstinline $X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1316 For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist 1314 1317 % Don't use predefined: keep this out of prelude.cf. 1315 1318 \begin{lstlisting} … … 1324 1327 \begin{lstlisting} 1325 1328 long int li; 1326 void eat_double( double ); @\use{eat_double}@1327 eat_double(-li ); // @\rewrite@eat_double( -?( li ) );1328 \end{lstlisting} 1329 The valid interpretations of ``\lstinline $-li$'' (assuming no extended integer types exist) are1329 void eat_double( double );§\use{eat_double}§ 1330 eat_double(-li ); // §\rewrite§ eat_double( -?( li ) ); 1331 \end{lstlisting} 1332 The valid interpretations of ``\lstinline@-li@'' (assuming no extended integer types exist) are 1330 1333 \begin{center} 1331 1334 \begin{tabular}{llc} interpretation & result type & expression conversion cost \\ 1332 1335 \hline 1333 \lstinline $-?( (int)li )$ & \lstinline$int$& (unsafe) \\1334 \lstinline $-?( (unsigned)li)$ & \lstinline$unsigned int$& (unsafe) \\1335 \lstinline $-?( (long)li)$ & \lstinline$long$& 0 \\1336 \lstinline $-?( (long unsigned int)li)$ & \lstinline$long unsigned int$& 1 \\1337 \lstinline $-?( (long long int)li)$ & \lstinline$long long int$& 2 \\1338 \lstinline $-?( (long long unsigned int)li)$ & \lstinline$long long unsigned int$& 3 \\1339 \lstinline $-?( (float)li)$ & \lstinline$float$& 4 \\1340 \lstinline $-?( (double)li)$ & \lstinline$double$& 5 \\1341 \lstinline $-?( (long double)li)$ & \lstinline$long double$& 6 \\1342 \lstinline $-?( (_Complex float)li)$ & \lstinline$float$& (unsafe) \\1343 \lstinline $-?( (_Complex double)li)$ & \lstinline$double$& (unsafe) \\1344 \lstinline $-?( (_Complex long double)li)$ & \lstinline$long double$& (unsafe) \\1336 \lstinline@-?( (int)li )@ & \lstinline@int@ & (unsafe) \\ 1337 \lstinline@-?( (unsigned)li)@ & \lstinline@unsigned int@ & (unsafe) \\ 1338 \lstinline@-?( (long)li)@ & \lstinline@long@ & 0 \\ 1339 \lstinline@-?( (long unsigned int)li)@ & \lstinline@long unsigned int@ & 1 \\ 1340 \lstinline@-?( (long long int)li)@ & \lstinline@long long int@ & 2 \\ 1341 \lstinline@-?( (long long unsigned int)li)@ & \lstinline@long long unsigned int@& 3 \\ 1342 \lstinline@-?( (float)li)@ & \lstinline@float@ & 4 \\ 1343 \lstinline@-?( (double)li)@ & \lstinline@double@ & 5 \\ 1344 \lstinline@-?( (long double)li)@ & \lstinline@long double@ & 6 \\ 1345 \lstinline@-?( (_Complex float)li)@ & \lstinline@float@ & (unsafe) \\ 1346 \lstinline@-?( (_Complex double)li)@ & \lstinline@double@ & (unsafe) \\ 1347 \lstinline@-?( (_Complex long double)li)@ & \lstinline@long double@ & (unsafe) \\ 1345 1348 \end{tabular} 1346 1349 \end{center} 1347 The valid interpretations of the \lstinline $eat_double$call, with the cost of the argument conversion and the cost of the entire expression, are1350 The valid interpretations of the \lstinline@eat_double@ call, with the cost of the argument conversion and the cost of the entire expression, are 1348 1351 \begin{center} 1349 1352 \begin{tabular}{lcc} interpretation & argument cost & expression cost \\ 1350 1353 \hline 1351 \lstinline $eat_double( (double)-?( (int)li) )$& 7 & (unsafe) \\1352 \lstinline $eat_double( (double)-?( (unsigned)li) )$& 6 & (unsafe) \\1353 \lstinline $eat_double( (double)-?(li) )$& 5 & \(0+5=5\) \\1354 \lstinline $eat_double( (double)-?( (long unsigned int)li) )$& 4 & \(1+4=5\) \\1355 \lstinline $eat_double( (double)-?( (long long int)li) )$& 3 & \(2+3=5\) \\1356 \lstinline $eat_double( (double)-?( (long long unsigned int)li) )$& 2 & \(3+2=5\) \\1357 \lstinline $eat_double( (double)-?( (float)li) )$& 1 & \(4+1=5\) \\1358 \lstinline $eat_double( (double)-?( (double)li) )$& 0 & \(5+0=5\) \\1359 \lstinline $eat_double( (double)-?( (long double)li) )$& (unsafe) & (unsafe) \\1360 \lstinline $eat_double( (double)-?( (_Complex float)li) )$& (unsafe) & (unsafe) \\1361 \lstinline $eat_double( (double)-?( (_Complex double)li) )$& (unsafe) & (unsafe) \\1362 \lstinline $eat_double( (double)-?( (_Complex long double)li) )$& (unsafe) & (unsafe) \\1354 \lstinline@eat_double( (double)-?( (int)li) )@ & 7 & (unsafe) \\ 1355 \lstinline@eat_double( (double)-?( (unsigned)li) )@ & 6 & (unsafe) \\ 1356 \lstinline@eat_double( (double)-?(li) )@ & 5 & \(0+5=5\) \\ 1357 \lstinline@eat_double( (double)-?( (long unsigned int)li) )@ & 4 & \(1+4=5\) \\ 1358 \lstinline@eat_double( (double)-?( (long long int)li) )@ & 3 & \(2+3=5\) \\ 1359 \lstinline@eat_double( (double)-?( (long long unsigned int)li) )@& 2 & \(3+2=5\) \\ 1360 \lstinline@eat_double( (double)-?( (float)li) )@ & 1 & \(4+1=5\) \\ 1361 \lstinline@eat_double( (double)-?( (double)li) )@ & 0 & \(5+0=5\) \\ 1362 \lstinline@eat_double( (double)-?( (long double)li) )@ & (unsafe) & (unsafe) \\ 1363 \lstinline@eat_double( (double)-?( (_Complex float)li) )@ & (unsafe) & (unsafe) \\ 1364 \lstinline@eat_double( (double)-?( (_Complex double)li) )@ & (unsafe) & (unsafe) \\ 1365 \lstinline@eat_double( (double)-?( (_Complex long double)li) )@ & (unsafe) & (unsafe) \\ 1363 1366 \end{tabular} 1364 1367 \end{center} 1365 Each has result type \lstinline $void$, so the best must be selected.1368 Each has result type \lstinline@void@, so the best must be selected. 1366 1369 The interpretations involving unsafe conversions are discarded. 1367 1370 The remainder have equal expression conversion costs, so the 1368 1371 ``highest argument conversion cost'' rule is invoked, and the chosen interpretation is 1369 \lstinline $eat_double( (double)-?(li) )$.1370 1371 1372 \subsubsection {The \lstinline$sizeof$ and \lstinline$_Alignof$operators}1372 \lstinline@eat_double( (double)-?(li) )@. 1373 1374 1375 \subsubsection[The sizeof and \_Alignof operators]{The \lstinline@sizeof@ and \lstinline@_Alignof@ operators} 1373 1376 1374 1377 \constraints 1375 The operand of \lstinline$sizeof$ or \lstinline$_Alignof$ shall not be \lstinline$type$, 1376 \lstinline$dtype$, or \lstinline$ftype$. 1377 1378 When the \lstinline$sizeof$\use{sizeof} operator is applied to an expression, the expression shall have exactly one \Index{interpretation}\index{ambiguous interpretation}, which shall be unambiguous. \semantics A \lstinline$sizeof$ or \lstinline$_Alignof$ expression has one interpretation, of type \lstinline$size_t$. 1379 1380 When \lstinline$sizeof$ is applied to an identifier declared by a \nonterm{type-declaration} or a 1378 The operand of \lstinline@sizeof@ or \lstinline@_Alignof@ shall not be \lstinline@type@, \lstinline@dtype@, or \lstinline@ftype@. 1379 1380 When the \lstinline@sizeof@\use{sizeof} operator is applied to an expression, the expression shall have exactly one \Index{interpretation}\index{ambiguous interpretation}, which shall be unambiguous. \semantics A \lstinline@sizeof@ or \lstinline@_Alignof@ expression has one interpretation, of type \lstinline@size_t@. 1381 1382 When \lstinline@sizeof@ is applied to an identifier declared by a \nonterm{type-declaration} or a 1381 1383 \nonterm{type-parameter}, it yields the size in bytes of the type that implements the operand. 1382 1384 When the operand is an opaque type or an inferred type parameter\index{inferred parameter}, the expression is not a constant expression. 1383 1385 1384 When \lstinline $_Alignof$is applied to an identifier declared by a \nonterm{type-declaration} or a1386 When \lstinline@_Alignof@ is applied to an identifier declared by a \nonterm{type-declaration} or a 1385 1387 \nonterm{type-parameter}, it yields the alignment requirement of the type that implements the operand. 1386 1388 When the operand is an opaque type or an inferred type parameter\index{inferred parameter}, the expression is not a constant expression. … … 1389 1391 otype Pair = struct { int first, second; }; 1390 1392 size_t p_size = sizeof(Pair); // constant expression 1391 extern otype Rational; @\use{Rational}@1393 extern otype Rational;§\use{Rational}§ 1392 1394 size_t c_size = sizeof(Rational); // non-constant expression 1393 1395 forall(type T) T f(T p1, T p2) { … … 1396 1398 } 1397 1399 \end{lstlisting} 1398 ``\lstinline $sizeof Rational$'', although not statically known, is fixed.1399 Within \lstinline $f()$,1400 ``\lstinline $sizeof(T)$'' is fixed for each call of \lstinline$f()$, but may vary from call to call.1400 ``\lstinline@sizeof Rational@'', although not statically known, is fixed. 1401 Within \lstinline@f()@, 1402 ``\lstinline@sizeof(T)@'' is fixed for each call of \lstinline@f()@, but may vary from call to call. 1401 1403 \end{rationale} 1402 1404 … … 1407 1409 \lhs{cast-expression} 1408 1410 \rhs \nonterm{unary-expression} 1409 \rhs \lstinline $($ \nonterm{type-name} \lstinline$)$\nonterm{cast-expression}1411 \rhs \lstinline@(@ \nonterm{type-name} \lstinline@)@ \nonterm{cast-expression} 1410 1412 \end{syntax} 1411 1413 1412 1414 \constraints 1413 The \nonterm{type-name} in a \nonterm{cast-expression} shall not be \lstinline $type$,1414 \lstinline $dtype$, or \lstinline$ftype$.1415 The \nonterm{type-name} in a \nonterm{cast-expression} shall not be \lstinline@type@, 1416 \lstinline@dtype@, or \lstinline@ftype@. 1415 1417 1416 1418 \semantics 1417 1419 1418 In a \Index{cast expression} ``\lstinline $($\nonterm{type-name}\lstinline$)e$'', if1419 \nonterm{type-name} is the type of an interpretation of \lstinline $e$, then that interpretation is the only interpretation of the cast expression;1420 otherwise, \lstinline $e$shall have some interpretation that can be converted to \nonterm{type-name}, and the interpretation of the cast expression is the cast of the interpretation that can be converted at the lowest cost.1420 In a \Index{cast expression} ``\lstinline@(@\nonterm{type-name}\lstinline@)e@'', if 1421 \nonterm{type-name} is the type of an interpretation of \lstinline@e@, then that interpretation is the only interpretation of the cast expression; 1422 otherwise, \lstinline@e@ shall have some interpretation that can be converted to \nonterm{type-name}, and the interpretation of the cast expression is the cast of the interpretation that can be converted at the lowest cost. 1421 1423 The cast expression's interpretation is ambiguous\index{ambiguous interpretation} if more than one interpretation can be converted at the lowest cost or if the selected interpretation is ambiguous. 1422 1424 … … 1431 1433 \lhs{multiplicative-expression} 1432 1434 \rhs \nonterm{cast-expression} 1433 \rhs \nonterm{multiplicative-expression} \lstinline $*$\nonterm{cast-expression}1434 \rhs \nonterm{multiplicative-expression} \lstinline $/$\nonterm{cast-expression}1435 \rhs \nonterm{multiplicative-expression} \lstinline $%$\nonterm{cast-expression}1435 \rhs \nonterm{multiplicative-expression} \lstinline@*@ \nonterm{cast-expression} 1436 \rhs \nonterm{multiplicative-expression} \lstinline@/@ \nonterm{cast-expression} 1437 \rhs \nonterm{multiplicative-expression} \lstinline@%@ \nonterm{cast-expression} 1436 1438 \end{syntax} 1437 1439 1438 1440 \rewriterules 1439 1441 \begin{lstlisting} 1440 a * b @\rewrite@ ?*?( a, b )@\use{?*?}@1441 a / b @\rewrite@ ?/?( a, b )@\use{?/?}@1442 a % b @\rewrite@ ?%?( a, b )@\use{?%?}@1442 a * b §\rewrite§ ?*?( a, b )§\use{?*?}§ 1443 a / b §\rewrite§ ?/?( a, b )§\use{?/?}§ 1444 a % b §\rewrite§ ?%?( a, b )§\use{?%?}§ 1443 1445 \end{lstlisting} 1444 1446 … … 1467 1469 ?*?( _Complex long double, _Complex long double ), ?/?( _Complex long double, _Complex long double ); 1468 1470 \end{lstlisting} 1469 For every extended integer type \lstinline $X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1471 For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist 1470 1472 % Don't use predefined: keep this out of prelude.cf. 1471 1473 \begin{lstlisting} … … 1485 1487 int i; 1486 1488 long li; 1487 void eat_double( double ); @\use{eat_double}@1489 void eat_double( double );§\use{eat_double}§ 1488 1490 eat_double( li % i ); 1489 1491 \end{lstlisting} 1490 ``\lstinline $li % i$'' is rewritten as ``\lstinline$?%?(li, i )$''.1491 The valid interpretations of \lstinline $?%?(li, i )$, the cost\index{conversion cost} of converting their arguments, and the cost of converting the result to \lstinline$double$(assuming no extended integer types are present ) are1492 ``\lstinline@li % i@'' is rewritten as ``\lstinline@?%?(li, i )@''. 1493 The valid interpretations of \lstinline@?%?(li, i )@, the cost\index{conversion cost} of converting their arguments, and the cost of converting the result to \lstinline@double@ (assuming no extended integer types are present ) are 1492 1494 \begin{center} 1493 1495 \begin{tabular}{lcc} interpretation & argument cost & result cost \\ 1494 1496 \hline 1495 \lstinline $ ?%?( (int)li, i )$& (unsafe) & 6 \\1496 \lstinline $ ?%?( (unsigned)li,(unsigned)i )$& (unsafe) & 5 \\1497 \lstinline $ ?%?( li, (long)i )$& 1 & 4 \\1498 \lstinline $ ?%?( (long unsigned)li,(long unsigned)i )$& 3 & 3 \\1499 \lstinline $ ?%?( (long long)li,(long long)i )$& 5 & 2 \\1500 \lstinline $ ?%?( (long long unsigned)li, (long long unsigned)i )$& 7 & 1 \\1497 \lstinline@ ?%?( (int)li, i )@ & (unsafe) & 6 \\ 1498 \lstinline@ ?%?( (unsigned)li,(unsigned)i )@ & (unsafe) & 5 \\ 1499 \lstinline@ ?%?( li, (long)i )@ & 1 & 4 \\ 1500 \lstinline@ ?%?( (long unsigned)li,(long unsigned)i )@ & 3 & 3 \\ 1501 \lstinline@ ?%?( (long long)li,(long long)i )@ & 5 & 2 \\ 1502 \lstinline@ ?%?( (long long unsigned)li, (long long unsigned)i )@ & 7 & 1 \\ 1501 1503 \end{tabular} 1502 1504 \end{center} 1503 The best interpretation of \lstinline $eat_double( li, i )$is1504 \lstinline $eat_double( (double)?%?(li, (long)i ))$, which has no unsafe conversions and the lowest total cost.1505 1506 \begin{rationale} 1507 {\c11} defines most arithmetic operations to apply an \Index{integer promotion} to any argument that belongs to a type that has an \Index{integer conversion rank} less than that of \lstinline $int$.If1508 \lstinline $s$ is a \lstinline$short int$, ``\lstinline$s *s$'' does not have type \lstinline$short int$;1509 it is treated as ``\lstinline $( (int)s ) * ( (int)s )$'', and has type \lstinline$int$. \CFA matches that pattern;1510 it does not predefine ``\lstinline $short ?*?( short, short )$''.1505 The best interpretation of \lstinline@eat_double( li, i )@ is 1506 \lstinline@eat_double( (double)?%?(li, (long)i ))@, which has no unsafe conversions and the lowest total cost. 1507 1508 \begin{rationale} 1509 {\c11} defines most arithmetic operations to apply an \Index{integer promotion} to any argument that belongs to a type that has an \Index{integer conversion rank} less than that of \lstinline@int@.If 1510 \lstinline@s@ is a \lstinline@short int@, ``\lstinline@s *s@'' does not have type \lstinline@short int@; 1511 it is treated as ``\lstinline@( (int)s ) * ( (int)s )@'', and has type \lstinline@int@. \CFA matches that pattern; 1512 it does not predefine ``\lstinline@short ?*?( short, short )@''. 1511 1513 1512 1514 These ``missing'' operators limit polymorphism. … … 1517 1519 square( s ); 1518 1520 \end{lstlisting} 1519 Since \CFA does not define a multiplication operator for \lstinline $short int$,1520 \lstinline $square( s )$ is treated as \lstinline$square( (int)s )$, and the result has type1521 \lstinline $int$.1521 Since \CFA does not define a multiplication operator for \lstinline@short int@, 1522 \lstinline@square( s )@ is treated as \lstinline@square( (int)s )@, and the result has type 1523 \lstinline@int@. 1522 1524 This is mildly surprising, but it follows the {\c11} operator pattern. 1523 1525 … … 1529 1531 \end{lstlisting} 1530 1532 This has no valid interpretations, because \CFA has no conversion from ``array of 1531 \lstinline $short int$'' to ``array of \lstinline$int$''.1533 \lstinline@short int@'' to ``array of \lstinline@int@''. 1532 1534 The alternatives in such situations include 1533 1535 \begin{itemize} 1534 1536 \item 1535 Defining monomorphic overloadings of \lstinline $product$ for \lstinline$short$and the other1537 Defining monomorphic overloadings of \lstinline@product@ for \lstinline@short@ and the other 1536 1538 ``small'' types. 1537 1539 \item 1538 Defining ``\lstinline $short ?*?( short, short )$'' within the scope containing the call to1539 \lstinline $product$.1540 \item 1541 Defining \lstinline $product$to take as an argument a conversion function from the ``small'' type to the operator's argument type.1540 Defining ``\lstinline@short ?*?( short, short )@'' within the scope containing the call to 1541 \lstinline@product@. 1542 \item 1543 Defining \lstinline@product@ to take as an argument a conversion function from the ``small'' type to the operator's argument type. 1542 1544 \end{itemize} 1543 1545 \end{rationale} … … 1549 1551 \lhs{additive-expression} 1550 1552 \rhs \nonterm{multiplicative-expression} 1551 \rhs \nonterm{additive-expression} \lstinline $+$\nonterm{multiplicative-expression}1552 \rhs \nonterm{additive-expression} \lstinline $-$\nonterm{multiplicative-expression}1553 \rhs \nonterm{additive-expression} \lstinline@+@ \nonterm{multiplicative-expression} 1554 \rhs \nonterm{additive-expression} \lstinline@-@ \nonterm{multiplicative-expression} 1553 1555 \end{syntax} 1554 1556 1555 1557 \rewriterules 1556 1558 \begin{lstlisting} 1557 a + b @\rewrite@ ?+?( a, b )@\use{?+?}@1558 a - b @\rewrite@ ?-?( a, b )@\use{?-?}@1559 a + b §\rewrite§ ?+?( a, b )§\use{?+?}§ 1560 a - b §\rewrite§ ?-?( a, b )§\use{?-?}§ 1559 1561 \end{lstlisting} 1560 1562 … … 1609 1611 * ?-?( _Atomic const restrict volatile T *, _Atomic const restrict volatile T * ); 1610 1612 \end{lstlisting} 1611 For every extended integer type \lstinline $X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1613 For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist 1612 1614 % Don't use predefined: keep this out of prelude.cf. 1613 1615 \begin{lstlisting} … … 1619 1621 1620 1622 \begin{rationale} 1621 \lstinline $ptrdiff_t$ is an implementation-defined identifier defined in \lstinline$<stddef.h>$that is synonymous with a signed integral type that is large enough to hold the difference between two pointers.1623 \lstinline@ptrdiff_t@ is an implementation-defined identifier defined in \lstinline@<stddef.h>@ that is synonymous with a signed integral type that is large enough to hold the difference between two pointers. 1622 1624 It seems reasonable to use it for pointer addition as well. (This is technically a difference between \CFA and C, which only specifies that pointer addition uses an \emph{integral} argument.) Hence it is also used for subscripting, which is defined in terms of pointer addition. 1623 The {\c11} standard uses \lstinline $size_t$ in several cases where a library function takes an argument that is used as a subscript, but \lstinline$size_t$is unsuitable here because it is an unsigned type.1625 The {\c11} standard uses \lstinline@size_t@ in several cases where a library function takes an argument that is used as a subscript, but \lstinline@size_t@ is unsuitable here because it is an unsigned type. 1624 1626 \end{rationale} 1625 1627 … … 1630 1632 \lhs{shift-expression} 1631 1633 \rhs \nonterm{additive-expression} 1632 \rhs \nonterm{shift-expression} \lstinline $<<$\nonterm{additive-expression}1633 \rhs \nonterm{shift-expression} \lstinline $>>$\nonterm{additive-expression}1634 \rhs \nonterm{shift-expression} \lstinline@<<@ \nonterm{additive-expression} 1635 \rhs \nonterm{shift-expression} \lstinline@>>@ \nonterm{additive-expression} 1634 1636 \end{syntax} 1635 1637 1636 1638 \rewriterules \use{?>>?}%use{?<<?} 1637 1639 \begin{lstlisting} 1638 a << b @\rewrite@?<<?( a, b )1639 a >> b @\rewrite@?>>?( a, b )1640 a << b §\rewrite§ ?<<?( a, b ) 1641 a >> b §\rewrite§ ?>>?( a, b ) 1640 1642 \end{lstlisting} 1641 1643 … … 1649 1651 long long unsigned int ?<<?( long long unsigned int, int ), ?>>?( long long unsigned int, int); 1650 1652 \end{lstlisting} 1651 For every extended integer type \lstinline $X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1653 For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist 1652 1654 % Don't use predefined: keep this out of prelude.cf. 1653 1655 \begin{lstlisting} … … 1669 1671 \lhs{relational-expression} 1670 1672 \rhs \nonterm{shift-expression} 1671 \rhs \nonterm{relational-expression} \lstinline $< $\nonterm{shift-expression}1672 \rhs \nonterm{relational-expression} \lstinline $> $\nonterm{shift-expression}1673 \rhs \nonterm{relational-expression} \lstinline $<=$\nonterm{shift-expression}1674 \rhs \nonterm{relational-expression} \lstinline $>=$\nonterm{shift-expression}1673 \rhs \nonterm{relational-expression} \lstinline@< @ \nonterm{shift-expression} 1674 \rhs \nonterm{relational-expression} \lstinline@> @ \nonterm{shift-expression} 1675 \rhs \nonterm{relational-expression} \lstinline@<=@ \nonterm{shift-expression} 1676 \rhs \nonterm{relational-expression} \lstinline@>=@ \nonterm{shift-expression} 1675 1677 \end{syntax} 1676 1678 1677 1679 \rewriterules\use{?>?}\use{?>=?}%use{?<?}%use{?<=?} 1678 1680 \begin{lstlisting} 1679 a < b @\rewrite@?<?( a, b )1680 a > b @\rewrite@?>?( a, b )1681 a <= b @\rewrite@?<=?( a, b )1682 a >= b @\rewrite@?>=?( a, b )1681 a < b §\rewrite§ ?<?( a, b ) 1682 a > b §\rewrite§ ?>?( a, b ) 1683 a <= b §\rewrite§ ?<=?( a, b ) 1684 a >= b §\rewrite§ ?>=?( a, b ) 1683 1685 \end{lstlisting} 1684 1686 … … 1712 1714 ?>=?( _Atomic const restrict volatile DT *, _Atomic const restrict volatile DT * ); 1713 1715 \end{lstlisting} 1714 For every extended integer type \lstinline $X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1716 For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist 1715 1717 % Don't use predefined: keep this out of prelude.cf. 1716 1718 \begin{lstlisting} … … 1730 1732 \lhs{equality-expression} 1731 1733 \rhs \nonterm{relational-expression} 1732 \rhs \nonterm{equality-expression} \lstinline $==$\nonterm{relational-expression}1733 \rhs \nonterm{equality-expression} \lstinline $!=$\nonterm{relational-expression}1734 \rhs \nonterm{equality-expression} \lstinline@==@ \nonterm{relational-expression} 1735 \rhs \nonterm{equality-expression} \lstinline@!=@ \nonterm{relational-expression} 1734 1736 \end{syntax} 1735 1737 1736 1738 \rewriterules 1737 1739 \begin{lstlisting} 1738 a == b @\rewrite@ ?==?( a, b )@\use{?==?}@1739 a != b @\rewrite@ ?!=?( a, b )@\use{?"!=?}@1740 a == b §\rewrite§ ?==?( a, b )§\use{?==?}§ 1741 a != b §\rewrite§ ?!=?( a, b )§\use{?"!=?}§ 1740 1742 \end{lstlisting} 1741 1743 … … 1790 1792 ?==?( forall( ftype FT2) FT2*, forall( ftype FT3) FT3 * ), ?!=?( forall( ftype FT2) FT2*, forall( ftype FT3) FT3 * ); 1791 1793 \end{lstlisting} 1792 For every extended integer type \lstinline $X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1794 For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist 1793 1795 % Don't use predefined: keep this out of prelude.cf. 1794 1796 \begin{lstlisting} … … 1798 1800 1799 1801 \begin{rationale} 1800 The polymorphic equality operations come in three styles: comparisons between pointers of compatible types, between pointers to \lstinline $void$and pointers to object types or incomplete types, and between the \Index{null pointer} constant and pointers to any type.1802 The polymorphic equality operations come in three styles: comparisons between pointers of compatible types, between pointers to \lstinline@void@ and pointers to object types or incomplete types, and between the \Index{null pointer} constant and pointers to any type. 1801 1803 In the last case, a special constraint rule for null pointer constant operands has been replaced by a consequence of the \CFA type system. 1802 1804 \end{rationale} … … 1819 1821 \lhs{AND-expression} 1820 1822 \rhs \nonterm{equality-expression} 1821 \rhs \nonterm{AND-expression} \lstinline $&$\nonterm{equality-expression}1823 \rhs \nonterm{AND-expression} \lstinline@&@ \nonterm{equality-expression} 1822 1824 \end{syntax} 1823 1825 1824 1826 \rewriterules 1825 1827 \begin{lstlisting} 1826 a & b @\rewrite@ ?&?( a, b )@\use{?&?}@1828 a & b §\rewrite§ ?&?( a, b )§\use{?&?}§ 1827 1829 \end{lstlisting} 1828 1830 … … 1836 1838 long long unsigned int ?&?( long long unsigned int, long long unsigned int ); 1837 1839 \end{lstlisting} 1838 For every extended integer type \lstinline $X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1840 For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist 1839 1841 % Don't use predefined: keep this out of prelude.cf. 1840 1842 \begin{lstlisting} … … 1851 1853 \lhs{exclusive-OR-expression} 1852 1854 \rhs \nonterm{AND-expression} 1853 \rhs \nonterm{exclusive-OR-expression} \lstinline $^$\nonterm{AND-expression}1855 \rhs \nonterm{exclusive-OR-expression} \lstinline@^@ \nonterm{AND-expression} 1854 1856 \end{syntax} 1855 1857 1856 1858 \rewriterules 1857 1859 \begin{lstlisting} 1858 a ^ b @\rewrite@ ?^?( a, b )@\use{?^?}@1860 a ^ b §\rewrite§ ?^?( a, b )§\use{?^?}§ 1859 1861 \end{lstlisting} 1860 1862 … … 1868 1870 long long unsigned int ?^?( long long unsigned int, long long unsigned int ); 1869 1871 \end{lstlisting} 1870 For every extended integer type \lstinline $X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1872 For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist 1871 1873 % Don't use predefined: keep this out of prelude.cf. 1872 1874 \begin{lstlisting} … … 1883 1885 \lhs{inclusive-OR-expression} 1884 1886 \rhs \nonterm{exclusive-OR-expression} 1885 \rhs \nonterm{inclusive-OR-expression} \lstinline $|$\nonterm{exclusive-OR-expression}1887 \rhs \nonterm{inclusive-OR-expression} \lstinline@|@ \nonterm{exclusive-OR-expression} 1886 1888 \end{syntax} 1887 1889 1888 1890 \rewriterules\use{?"|?} 1889 1891 \begin{lstlisting} 1890 a | b @\rewrite@?|?( a, b )1892 a | b §\rewrite§ ?|?( a, b ) 1891 1893 \end{lstlisting} 1892 1894 … … 1900 1902 long long unsigned int ?|?( long long unsigned int, long long unsigned int ); 1901 1903 \end{lstlisting} 1902 For every extended integer type \lstinline $X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1904 For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist 1903 1905 % Don't use predefined: keep this out of prelude.cf. 1904 1906 \begin{lstlisting} … … 1915 1917 \lhs{logical-AND-expression} 1916 1918 \rhs \nonterm{inclusive-OR-expression} 1917 \rhs \nonterm{logical-AND-expression} \lstinline $&&$\nonterm{inclusive-OR-expression}1919 \rhs \nonterm{logical-AND-expression} \lstinline@&&@ \nonterm{inclusive-OR-expression} 1918 1920 \end{syntax} 1919 1921 1920 \semantics The operands of the expression ``\lstinline $a && b$'' are treated as1921 ``\lstinline $(int)((a)!=0)$'' and ``\lstinline$(int)((b)!=0)$'', which shall both be unambiguous.1922 The expression has only one interpretation, which is of type \lstinline $int$.1923 \begin{rationale} 1924 When the operands of a logical expression are values of built-in types, and ``\lstinline $!=$'' has not been redefined for those types, the compiler can optimize away the function calls.1925 1926 A common C idiom omits comparisons to \lstinline $0$in the controlling expressions of loops and1927 \lstinline $if$statements.1928 For instance, the loop below iterates as long as \lstinline $rp$ points at a \lstinline$Rational$value that is non-zero.1929 1930 \begin{lstlisting} 1931 extern otype Rational; @\use{Rational}@1932 extern const Rational 0; @\use{0}@1922 \semantics The operands of the expression ``\lstinline@a && b@'' are treated as 1923 ``\lstinline@(int)((a)!=0)@'' and ``\lstinline@(int)((b)!=0)@'', which shall both be unambiguous. 1924 The expression has only one interpretation, which is of type \lstinline@int@. 1925 \begin{rationale} 1926 When the operands of a logical expression are values of built-in types, and ``\lstinline@!=@'' has not been redefined for those types, the compiler can optimize away the function calls. 1927 1928 A common C idiom omits comparisons to \lstinline@0@ in the controlling expressions of loops and 1929 \lstinline@if@ statements. 1930 For instance, the loop below iterates as long as \lstinline@rp@ points at a \lstinline@Rational@ value that is non-zero. 1931 1932 \begin{lstlisting} 1933 extern otype Rational;§\use{Rational}§ 1934 extern const Rational 0;§\use{0}§ 1933 1935 extern int ?!=?( Rational, Rational ); 1934 1936 Rational *rp; 1935 1937 while ( rp && *rp ) { ... } 1936 1938 \end{lstlisting} 1937 The logical expression calls the \lstinline $Rational$ inequality operator, passing it \lstinline$*rp$ and the \lstinline$Rational 0$, and getting a 1 or 0 as a result.1938 In contrast, {\CC} would apply a programmer-defined \lstinline $Rational$-to-\lstinline$int$ conversion to \lstinline$*rp$in the equivalent situation.1939 The conversion to \lstinline $int$would produce a general integer value, which is unfortunate, and possibly dangerous if the conversion was not written with this situation in mind.1939 The logical expression calls the \lstinline@Rational@ inequality operator, passing it \lstinline@*rp@ and the \lstinline@Rational 0@, and getting a 1 or 0 as a result. 1940 In contrast, {\CC} would apply a programmer-defined \lstinline@Rational@-to-\lstinline@int@ conversion to \lstinline@*rp@ in the equivalent situation. 1941 The conversion to \lstinline@int@ would produce a general integer value, which is unfortunate, and possibly dangerous if the conversion was not written with this situation in mind. 1940 1942 \end{rationale} 1941 1943 … … 1946 1948 \lhs{logical-OR-expression} 1947 1949 \rhs \nonterm{logical-AND-expression} 1948 \rhs \nonterm{logical-OR-expression} \lstinline $||$\nonterm{logical-AND-expression}1950 \rhs \nonterm{logical-OR-expression} \lstinline@||@ \nonterm{logical-AND-expression} 1949 1951 \end{syntax} 1950 1952 1951 1953 \semantics 1952 1954 1953 The operands of the expression ``\lstinline $a || b$'' are treated as ``\lstinline$(int)((a)!=0)$'' and ``\lstinline$(int)((b))!=0)$'', which shall both be unambiguous.1954 The expression has only one interpretation, which is of type \lstinline $int$.1955 The operands of the expression ``\lstinline@a || b@'' are treated as ``\lstinline@(int)((a)!=0)@'' and ``\lstinline@(int)((b))!=0)@'', which shall both be unambiguous. 1956 The expression has only one interpretation, which is of type \lstinline@int@. 1955 1957 1956 1958 … … 1960 1962 \lhs{conditional-expression} 1961 1963 \rhs \nonterm{logical-OR-expression} 1962 \rhs \nonterm{logical-OR-expression} \lstinline $?$\nonterm{expression}1963 \lstinline $:$\nonterm{conditional-expression}1964 \rhs \nonterm{logical-OR-expression} \lstinline@?@ \nonterm{expression} 1965 \lstinline@:@ \nonterm{conditional-expression} 1964 1966 \end{syntax} 1965 1967 1966 1968 \semantics 1967 In the conditional expression\use{?:} ``\lstinline $a?b:c$'', if the second and third operands both have an interpretation with \lstinline$void$ type, then the expression has an interpretation with type \lstinline$void$, equivalent to1969 In the conditional expression\use{?:} ``\lstinline@a?b:c@'', if the second and third operands both have an interpretation with \lstinline@void@ type, then the expression has an interpretation with type \lstinline@void@, equivalent to 1968 1970 \begin{lstlisting} 1969 1971 ( int)(( a)!=0) ? ( void)( b) : ( void)( c) 1970 1972 \end{lstlisting} 1971 1973 1972 If the second and third operands both have interpretations with non-\lstinline $void$ types, the expression is treated as if it were the call ``\lstinline$cond((a)!=0, b, c)$'', with \lstinline$cond$declared as1974 If the second and third operands both have interpretations with non-\lstinline@void@ types, the expression is treated as if it were the call ``\lstinline@cond((a)!=0, b, c)@'', with \lstinline@cond@ declared as 1973 1975 \begin{lstlisting} 1974 1976 forall( otype T ) T cond( int, T, T ); … … 2022 2024 rand() ? i : l; 2023 2025 \end{lstlisting} 2024 The best interpretation infers the expression's type to be \lstinline $long$and applies the safe2025 \lstinline $int$-to-\lstinline$long$ conversion to \lstinline$i$.2026 The best interpretation infers the expression's type to be \lstinline@long@ and applies the safe 2027 \lstinline@int@-to-\lstinline@long@ conversion to \lstinline@i@. 2026 2028 2027 2029 \begin{lstlisting} … … 2030 2032 rand() ? cip : vip; 2031 2033 \end{lstlisting} 2032 The expression has type \lstinline $const volatile int *$, with safe conversions applied to the second and third operands to add \lstinline$volatile$ and \lstinline$const$qualifiers, respectively.2034 The expression has type \lstinline@const volatile int *@, with safe conversions applied to the second and third operands to add \lstinline@volatile@ and \lstinline@const@ qualifiers, respectively. 2033 2035 2034 2036 \begin{lstlisting} 2035 2037 rand() ? cip : 0; 2036 2038 \end{lstlisting} 2037 The expression has type \lstinline $const int *$, with a specialization conversion applied to2038 \lstinline $0$.2039 The expression has type \lstinline@const int *@, with a specialization conversion applied to 2040 \lstinline@0@. 2039 2041 2040 2042 … … 2047 2049 \nonterm{assignment-expression} 2048 2050 \lhs{assignment-operator} one of 2049 \rhs \lstinline $=$\ \ \lstinline$*=$\ \ \lstinline$/=$\ \ \lstinline$%=$\ \ \lstinline$+=$\ \ \lstinline$-=$\ \2050 \lstinline $<<=$\ \ \lstinline$>>=$\ \ \lstinline$&=$\ \ \lstinline$^=$\ \ \lstinline$|=$2051 \rhs \lstinline@=@\ \ \lstinline@*=@\ \ \lstinline@/=@\ \ \lstinline@%=@\ \ \lstinline@+=@\ \ \lstinline@-=@\ \ 2052 \lstinline@<<=@\ \ \lstinline@>>=@\ \ \lstinline@&=@\ \ \lstinline@^=@\ \ \lstinline@|=@ 2051 2053 \end{syntax} 2052 2054 … … 2057 2059 \use{?>>=?}\use{?&=?}\use{?^=?}\use{?"|=?}%use{?<<=?} 2058 2060 \begin{lstlisting} 2059 a @$\leftarrow$@ b @\rewrite@ ?@$\leftarrow$@?( &( a ), b )2061 a §$\leftarrow$§ b §\rewrite§ ?§$\leftarrow$§?( &( a ), b ) 2060 2062 \end{lstlisting} 2061 2063 2062 2064 \semantics 2063 2065 Each interpretation of the left operand of an assignment expression is considered separately. 2064 For each interpretation that is a bit-field or is declared with the \lstinline $register$storage class specifier, the expression has one valid interpretation, with the type of the left operand.2066 For each interpretation that is a bit-field or is declared with the \lstinline@register@ storage class specifier, the expression has one valid interpretation, with the type of the left operand. 2065 2067 The right operand is cast to that type, and the assignment expression is ambiguous if either operand is. 2066 2068 For the remaining interpretations, the expression is rewritten, and the interpretations of the assignment expression are the interpretations of the corresponding function call. … … 2295 2297 \end{lstlisting} 2296 2298 \begin{rationale} 2297 The pattern of overloadings for simple assignment resembles that of pointer increment and decrement, except that the polymorphic pointer assignment functions declare a \lstinline $dtype$ parameter, instead of a \lstinline$type$parameter, because the left operand may be a pointer to an incomplete type.2298 \end{rationale} 2299 2300 For every complete structure or union type \lstinline $S$there exist2299 The pattern of overloadings for simple assignment resembles that of pointer increment and decrement, except that the polymorphic pointer assignment functions declare a \lstinline@dtype@ parameter, instead of a \lstinline@type@ parameter, because the left operand may be a pointer to an incomplete type. 2300 \end{rationale} 2301 2302 For every complete structure or union type \lstinline@S@ there exist 2301 2303 % Don't use predefined: keep this out of prelude.cf. 2302 2304 \begin{lstlisting} … … 2304 2306 \end{lstlisting} 2305 2307 2306 For every extended integer type \lstinline $X$there exist2308 For every extended integer type \lstinline@X@ there exist 2307 2309 % Don't use predefined: keep this out of prelude.cf. 2308 2310 \begin{lstlisting} … … 2310 2312 \end{lstlisting} 2311 2313 2312 For every complete enumerated type \lstinline $E$there exist2314 For every complete enumerated type \lstinline@E@ there exist 2313 2315 % Don't use predefined: keep this out of prelude.cf. 2314 2316 \begin{lstlisting} … … 2316 2318 \end{lstlisting} 2317 2319 \begin{rationale} 2318 The right-hand argument is \lstinline $int$ because enumeration constants have type \lstinline$int$.2320 The right-hand argument is \lstinline@int@ because enumeration constants have type \lstinline@int@. 2319 2321 \end{rationale} 2320 2322 … … 2577 2579 \end{lstlisting} 2578 2580 2579 For every extended integer type \lstinline $X$there exist2581 For every extended integer type \lstinline@X@ there exist 2580 2582 % Don't use predefined: keep this out of prelude.cf. 2581 2583 \begin{lstlisting} … … 2592 2594 \end{lstlisting} 2593 2595 2594 For every complete enumerated type \lstinline $E$there exist2596 For every complete enumerated type \lstinline@E@ there exist 2595 2597 % Don't use predefined: keep this out of prelude.cf. 2596 2598 \begin{lstlisting} … … 2613 2615 \lhs{expression} 2614 2616 \rhs \nonterm{assignment-expression} 2615 \rhs \nonterm{expression} \lstinline $,$\nonterm{assignment-expression}2617 \rhs \nonterm{expression} \lstinline@,@ \nonterm{assignment-expression} 2616 2618 \end{syntax} 2617 2619 2618 2620 \semantics 2619 In the comma expression ``\lstinline $a, b$'', the first operand is interpreted as2620 ``\lstinline $( void )(a)$'', which shall be unambiguous\index{ambiguous interpretation}.2621 In the comma expression ``\lstinline@a, b@'', the first operand is interpreted as 2622 ``\lstinline@( void )(a)@'', which shall be unambiguous\index{ambiguous interpretation}. 2621 2623 The interpretations of the expression are the interpretations of the second operand. 2622 2624 … … 2653 2655 { ... } 2654 2656 \end{lstlisting} 2655 Without the rule, \lstinline $Complex$would be a type in the first case, and a parameter name in the second.2657 Without the rule, \lstinline@Complex@ would be a type in the first case, and a parameter name in the second. 2656 2658 \end{rationale} 2657 2659 … … 2679 2681 \examples 2680 2682 \begin{lstlisting} 2681 struct point { @\impl{point}@2683 struct point {§\impl{point}§ 2682 2684 int x, y; 2683 2685 }; 2684 struct color_point { @\impl{color_point}@2686 struct color_point {§\impl{color_point}§ 2685 2687 enum { RED, BLUE, GREEN } color; 2686 2688 struct point; … … 2689 2691 cp.x = 0; 2690 2692 cp.color = RED; 2691 struct literal { @\impl{literal}@2693 struct literal {§\impl{literal}§ 2692 2694 enum { NUMBER, STRING } tag; 2693 2695 union { … … 2710 2712 \begin{syntax} 2711 2713 \lhs{forall-specifier} 2712 \rhs \lstinline $forall$ \lstinline$($ \nonterm{type-parameter-list} \lstinline$)$2714 \rhs \lstinline@forall@ \lstinline@(@ \nonterm{type-parameter-list} \lstinline@)@ 2713 2715 \end{syntax} 2714 2716 … … 2722 2724 } mkPair( T, T ); // illegal 2723 2725 \end{lstlisting} 2724 If an instance of \lstinline $struct Pair$was declared later in the current scope, what would the members' type be?2726 If an instance of \lstinline@struct Pair@ was declared later in the current scope, what would the members' type be? 2725 2727 \end{rationale} 2726 2728 \end{comment} … … 2729 2731 The \nonterm{type-parameter-list}s and assertions of the \nonterm{forall-specifier}s declare type identifiers, function and object identifiers with \Index{no linkage}. 2730 2732 2731 If, in the declaration ``\lstinline $T D$'', \lstinline$T$contains \nonterm{forall-specifier}s and2732 \lstinline $D$has the form2733 \begin{lstlisting} 2734 D( @\normalsize\nonterm{parameter-type-list}@)2735 \end{lstlisting} then a type identifier declared by one of the \nonterm{forall-specifier}s is an \define{inferred parameter} of the function declarator if and only if it is not an inferred parameter of a function declarator in \lstinline $D$, and it is used in the type of a parameter in the following2733 If, in the declaration ``\lstinline@T D@'', \lstinline@T@ contains \nonterm{forall-specifier}s and 2734 \lstinline@D@ has the form 2735 \begin{lstlisting} 2736 D( §\normalsize\nonterm{parameter-type-list}§ ) 2737 \end{lstlisting} then a type identifier declared by one of the \nonterm{forall-specifier}s is an \define{inferred parameter} of the function declarator if and only if it is not an inferred parameter of a function declarator in \lstinline@D@, and it is used in the type of a parameter in the following 2736 2738 \nonterm{type-parameter-list} or it and an inferred parameter are used as arguments of a 2737 2739 \Index{specification} in one of the \nonterm{forall-specifier}s. … … 2744 2746 If this restriction were lifted, it would be possible to write 2745 2747 \begin{lstlisting} 2746 forall( otype T ) T * alloc( void ); @\use{alloc}@int *p = alloc();2747 \end{lstlisting} 2748 Here \lstinline $alloc()$ would receive \lstinline$int$as an inferred argument, and return an2749 \lstinline $int *$.2750 In general, if a call to \lstinline $alloc()$ is a subexpression of an expression involving polymorphic functions and overloaded identifiers, there could be considerable distance between the call and the subexpression that causes \lstinline$T$to be bound.2751 2752 With the current restriction, \lstinline $alloc()$must be given an argument that determines2753 \lstinline $T$:2754 \begin{lstlisting} 2755 forall( otype T ) T * alloc( T initial_value ); @\use{alloc}@2748 forall( otype T ) T * alloc( void );§\use{alloc}§ int *p = alloc(); 2749 \end{lstlisting} 2750 Here \lstinline@alloc()@ would receive \lstinline@int@ as an inferred argument, and return an 2751 \lstinline@int *@. 2752 In general, if a call to \lstinline@alloc()@ is a subexpression of an expression involving polymorphic functions and overloaded identifiers, there could be considerable distance between the call and the subexpression that causes \lstinline@T@ to be bound. 2753 2754 With the current restriction, \lstinline@alloc()@ must be given an argument that determines 2755 \lstinline@T@: 2756 \begin{lstlisting} 2757 forall( otype T ) T * alloc( T initial_value );§\use{alloc}§ 2756 2758 \end{lstlisting} 2757 2759 \end{rationale} … … 2778 2780 forall( otype T ) T fT( T ); 2779 2781 \end{lstlisting} 2780 \lstinline $fi()$ takes an \lstinline$int$ and returns an \lstinline$int$. \lstinline$fT()$takes a2781 \lstinline $T$ and returns a \lstinline$T$, for any type \lstinline$T$.2782 \lstinline@fi()@ takes an \lstinline@int@ and returns an \lstinline@int@. \lstinline@fT()@ takes a 2783 \lstinline@T@ and returns a \lstinline@T@, for any type \lstinline@T@. 2782 2784 \begin{lstlisting} 2783 2785 int (*pfi )( int ) = fi; 2784 2786 forall( otype T ) T (*pfT )( T ) = fT; 2785 2787 \end{lstlisting} 2786 \lstinline $pfi$ and \lstinline$pfT$ are pointers to functions. \lstinline$pfT$is not polymorphic, but the function it points at is.2788 \lstinline@pfi@ and \lstinline@pfT@ are pointers to functions. \lstinline@pfT@ is not polymorphic, but the function it points at is. 2787 2789 \begin{lstlisting} 2788 2790 int (*fvpfi( void ))( int ) { … … 2793 2795 } 2794 2796 \end{lstlisting} 2795 \lstinline $fvpfi()$ and \lstinline$fvpfT()$ are functions taking no arguments and returning pointers to functions. \lstinline$fvpfT()$is monomorphic, but the function that its return value points at is polymorphic.2797 \lstinline@fvpfi()@ and \lstinline@fvpfT()@ are functions taking no arguments and returning pointers to functions. \lstinline@fvpfT()@ is monomorphic, but the function that its return value points at is polymorphic. 2796 2798 \begin{lstlisting} 2797 2799 forall( otype T ) int ( *fTpfi( T ) )( int ); … … 2799 2801 forall( otype T, otype U ) U ( *fTpfU( T ) )( U ); 2800 2802 \end{lstlisting} 2801 \lstinline $fTpfi()$is a polymorphic function that returns a pointer to a monomorphic function taking an integer and returning an integer.2802 It could return \lstinline $pfi$. \lstinline$fTpfT()$is subtle: it is a polymorphic function returning a \emph{monomorphic} function taking and returning2803 \lstinline $T$, where \lstinline$T$ is an inferred parameter of \lstinline$fTpfT()$.2804 For instance, in the expression ``\lstinline $fTpfT(17)$'', \lstinline$T$ is inferred to be \lstinline$int$, and the returned value would have type \lstinline$int ( * )( int )$. ``\lstinline$fTpfT(17)(13)$'' and2805 ``\lstinline $fTpfT("yes")("no")$'' are legal, but ``\lstinline$fTpfT(17)("no")$'' is illegal.2806 \lstinline $fTpfU()$ is polymorphic ( in type \lstinline$T$), and returns a pointer to a function that is polymorphic ( in type \lstinline$U$). ``\lstinline$f5(17)("no")$'' is a legal expression of type2807 \lstinline $char *$.2803 \lstinline@fTpfi()@ is a polymorphic function that returns a pointer to a monomorphic function taking an integer and returning an integer. 2804 It could return \lstinline@pfi@. \lstinline@fTpfT()@ is subtle: it is a polymorphic function returning a \emph{monomorphic} function taking and returning 2805 \lstinline@T@, where \lstinline@T@ is an inferred parameter of \lstinline@fTpfT()@. 2806 For instance, in the expression ``\lstinline@fTpfT(17)@'', \lstinline@T@ is inferred to be \lstinline@int@, and the returned value would have type \lstinline@int ( * )( int )@. ``\lstinline@fTpfT(17)(13)@'' and 2807 ``\lstinline@fTpfT("yes")("no")@'' are legal, but ``\lstinline@fTpfT(17)("no")@'' is illegal. 2808 \lstinline@fTpfU()@ is polymorphic ( in type \lstinline@T@), and returns a pointer to a function that is polymorphic ( in type \lstinline@U@). ``\lstinline@f5(17)("no")@'' is a legal expression of type 2809 \lstinline@char *@. 2808 2810 \begin{lstlisting} 2809 2811 forall( otype T, otype U, otype V ) U * f( T *, U, V * const ); 2810 2812 forall( otype U, otype V, otype W ) U * g( V *, U, W * const ); 2811 2813 \end{lstlisting} 2812 The functions \lstinline $f()$ and \lstinline$g()$have compatible types.2814 The functions \lstinline@f()@ and \lstinline@g()@ have compatible types. 2813 2815 Let \(f\) and \(g\) be their types; 2814 then \(f_1\) = \lstinline $T$, \(f_2\) = \lstinline$U$, \(f_3\) = \lstinline$V$, \(g_1\)2815 = \lstinline $V$, \(g_2\) = \lstinline$U$, and \(g_3\) = \lstinline$W$.2816 then \(f_1\) = \lstinline@T@, \(f_2\) = \lstinline@U@, \(f_3\) = \lstinline@V@, \(g_1\) 2817 = \lstinline@V@, \(g_2\) = \lstinline@U@, and \(g_3\) = \lstinline@W@. 2816 2818 Replacing every \(f_i\) by \(g_i\) in \(f\) gives 2817 2819 \begin{lstlisting} … … 2819 2821 \end{lstlisting} which has a return type and parameter list that is compatible with \(g\). 2820 2822 \begin{rationale} 2821 The word ``\lstinline $type$'' in a forall specifier is redundant at the moment, but I want to leave room for inferred parameters of ordinary types in case parameterized types get added one day.2823 The word ``\lstinline@type@'' in a forall specifier is redundant at the moment, but I want to leave room for inferred parameters of ordinary types in case parameterized types get added one day. 2822 2824 2823 2825 Even without parameterized types, I might try to allow … … 2845 2847 \subsection{Type qualifiers} 2846 2848 2847 \CFA defines a new type qualifier \lstinline $lvalue$\impl{lvalue}\index{lvalue}.2849 \CFA defines a new type qualifier \lstinline@lvalue@\impl{lvalue}\index{lvalue}. 2848 2850 \begin{syntax} 2849 2851 \oldlhs{type-qualifier} 2850 \rhs \lstinline $lvalue$2852 \rhs \lstinline@lvalue@ 2851 2853 \end{syntax} 2852 2854 2853 2855 \constraints 2854 \ lstinline$restrict$\index{register@{\lstinline$restrict$}} Types other than type parameters and pointer types whose referenced type is an object type shall not be restrict-qualified.2856 \Indexc{restrict} Types other than type parameters and pointer types whose referenced type is an object type shall not be restrict-qualified. 2855 2857 2856 2858 \semantics 2857 An object's type may be a restrict-qualified type parameter. \lstinline$restrict$ does not establish any special semantics in that case. 2859 An object's type may be a restrict-qualified type parameter. 2860 \lstinline@restrict@ does not establish any special semantics in that case. 2858 2861 2859 2862 \begin{rationale} … … 2861 2864 \end{rationale} 2862 2865 2863 \lstinline $lvalue$may be used to qualify the return type of a function type.2864 Let \lstinline $T$be an unqualified version of a type;2866 \lstinline@lvalue@ may be used to qualify the return type of a function type. 2867 Let \lstinline@T@ be an unqualified version of a type; 2865 2868 then the result of calling a function with return type 2866 \lstinline $lvalue T$ is a \Index{modifiable lvalue} of type \lstinline$T$.2867 \lstinline $const$\use{const} and \lstinline$volatile$\use{volatile} qualifiers may also be added to indicate that the function result is a constant or volatile lvalue.2868 \begin{rationale} 2869 The \lstinline $const$ and \lstinline$volatile$ qualifiers can only be sensibly used to qualify the return type of a function if the \lstinline$lvalue$qualifier is also used.2869 \lstinline@lvalue T@ is a \Index{modifiable lvalue} of type \lstinline@T@. 2870 \lstinline@const@\use{const} and \lstinline@volatile@\use{volatile} qualifiers may also be added to indicate that the function result is a constant or volatile lvalue. 2871 \begin{rationale} 2872 The \lstinline@const@ and \lstinline@volatile@ qualifiers can only be sensibly used to qualify the return type of a function if the \lstinline@lvalue@ qualifier is also used. 2870 2873 \end{rationale} 2871 2874 … … 2874 2877 2875 2878 \begin{rationale} 2876 \lstinline $lvalue$ provides some of the functionality of {\CC}'s ``\lstinline$T&$'' ( reference to object of type \lstinline$T$) type.2879 \lstinline@lvalue@ provides some of the functionality of {\CC}'s ``\lstinline@T&@'' ( reference to object of type \lstinline@T@) type. 2877 2880 Reference types have four uses in {\CC}. 2878 2881 \begin{itemize} 2879 2882 \item 2880 They are necessary for user-defined operators that return lvalues, such as ``subscript'' and 2881 ``dereference''. 2882 2883 \item 2884 A reference can be used to define an alias for a complicated lvalue expression, as a way of getting some of the functionality of the Pascal \lstinline$with$ statement. 2883 They are necessary for user-defined operators that return lvalues, such as ``subscript'' and ``dereference''. 2884 2885 \item 2886 A reference can be used to define an alias for a complicated lvalue expression, as a way of getting some of the functionality of the Pascal \lstinline@with@ statement. 2885 2887 The following {\CC} code gives an example. 2886 2888 \begin{lstlisting} … … 2895 2897 A reference parameter can be used to allow a function to modify an argument without forcing the caller to pass the address of the argument. 2896 2898 This is most useful for user-defined assignment operators. 2897 In {\CC}, plain assignment is done by a function called ``\lstinline $operator=$'', and the two expressions2899 In {\CC}, plain assignment is done by a function called ``\lstinline@operator=@'', and the two expressions 2898 2900 \begin{lstlisting} 2899 2901 a = b; 2900 2902 operator=( a, b ); 2901 2903 \end{lstlisting} are equivalent. 2902 If \lstinline $a$ and \lstinline$b$ are of type \lstinline$T$, then the first parameter of \lstinline$operator=$ must have type ``\lstinline$T&$''.2904 If \lstinline@a@ and \lstinline@b@ are of type \lstinline@T@, then the first parameter of \lstinline@operator=@ must have type ``\lstinline@T&@''. 2903 2905 It cannot have type 2904 \lstinline $T$, because then assignment couldn't alter the variable, and it can't have type2905 ``\lstinline $T *$'', because the assignment would have to be written ``\lstinline$&a = b;$''.2906 2907 In the case of user-defined operators, this could just as well be handled by using pointer types and by changing the rewrite rules so that ``\lstinline $a = b;$'' is equivalent to2908 ``\lstinline $operator=(&( a), b )$''.2909 Reference parameters of ``normal'' functions are Bad Things, because they remove a useful property of C function calls: an argument can only be modified by a function if it is preceded by ``\lstinline $&$''.2906 \lstinline@T@, because then assignment couldn't alter the variable, and it can't have type 2907 ``\lstinline@T *@'', because the assignment would have to be written ``\lstinline@&a = b;@''. 2908 2909 In the case of user-defined operators, this could just as well be handled by using pointer types and by changing the rewrite rules so that ``\lstinline@a = b;@'' is equivalent to 2910 ``\lstinline@operator=(&( a), b )@''. 2911 Reference parameters of ``normal'' functions are Bad Things, because they remove a useful property of C function calls: an argument can only be modified by a function if it is preceded by ``\lstinline@&@''. 2910 2912 2911 2913 \item 2912 2914 References to \Index{const-qualified} types can be used instead of value parameters. Given the 2913 {\CC} function call ``\lstinline $fiddle( a_thing )$'', where the type of \lstinline$a_thing$is2914 \lstinline $Thing$, the type of \lstinline$fiddle$could be either of2915 {\CC} function call ``\lstinline@fiddle( a_thing )@'', where the type of \lstinline@a_thing@ is 2916 \lstinline@Thing@, the type of \lstinline@fiddle@ could be either of 2915 2917 \begin{lstlisting} 2916 2918 void fiddle( Thing ); 2917 2919 void fiddle( const Thing & ); 2918 2920 \end{lstlisting} 2919 If the second form is used, then constructors and destructors are not invoked to create a temporary variable at the call site ( and it is bad style for the caller to make any assumptions about such things), and within \lstinline $fiddle$the parameter is subject to the usual problems caused by aliases.2920 The reference form might be chosen for efficiency's sake if \lstinline $Thing$s are too large or their constructors or destructors are too expensive.2921 If the second form is used, then constructors and destructors are not invoked to create a temporary variable at the call site ( and it is bad style for the caller to make any assumptions about such things), and within \lstinline@fiddle@ the parameter is subject to the usual problems caused by aliases. 2922 The reference form might be chosen for efficiency's sake if \lstinline@Thing@s are too large or their constructors or destructors are too expensive. 2921 2923 An implementation may switch between them without causing trouble for well-behaved clients. 2922 2924 This leaves the implementor to define ``too large'' and ``too expensive''. … … 2926 2928 void fiddle( const volatile Thing ); 2927 2929 \end{lstlisting} with call-by-reference. 2928 Since it knows all about the size of \lstinline $Thing$s and the parameter passing mechanism, it should be able to come up with a better definition of ``too large'', and may be able to make a good guess at ``too expensive''.2930 Since it knows all about the size of \lstinline@Thing@s and the parameter passing mechanism, it should be able to come up with a better definition of ``too large'', and may be able to make a good guess at ``too expensive''. 2929 2931 \end{itemize} 2930 2932 … … 2946 2948 \begin{syntax} 2947 2949 \lhs{spec-definition} 2948 \rhs \lstinline $spec$\nonterm{identifier}2949 \lstinline $($ \nonterm{type-parameter-list} \lstinline$)$2950 \lstinline ${$ \nonterm{spec-declaration-list}\opt \lstinline$}$2950 \rhs \lstinline@spec@ \nonterm{identifier} 2951 \lstinline@(@ \nonterm{type-parameter-list} \lstinline@)@ 2952 \lstinline@{@ \nonterm{spec-declaration-list}\opt \lstinline@}@ 2951 2953 \lhs{spec-declaration-list} 2952 \rhs \nonterm{spec-declaration} \lstinline $;$2953 \rhs \nonterm{spec-declaration-list} \nonterm{spec-declaration} \lstinline $;$2954 \rhs \nonterm{spec-declaration} \lstinline@;@ 2955 \rhs \nonterm{spec-declaration-list} \nonterm{spec-declaration} \lstinline@;@ 2954 2956 \lhs{spec-declaration} 2955 2957 \rhs \nonterm{specifier-qualifier-list} \nonterm{declarator-list} 2956 2958 \lhs{declarator-list} 2957 2959 \rhs \nonterm{declarator} 2958 \rhs \nonterm{declarator-list} \lstinline $,$\nonterm{declarator}2960 \rhs \nonterm{declarator-list} \lstinline@,@ \nonterm{declarator} 2959 2961 \end{syntax} 2960 2962 \begin{rationale} … … 2978 2980 \rhs \nonterm{assertion-list} \nonterm{assertion} 2979 2981 \lhs{assertion} 2980 \rhs \lstinline $|$ \nonterm{identifier} \lstinline$($ \nonterm{type-name-list} \lstinline$)$2981 \rhs \lstinline $|$\nonterm{spec-declaration}2982 \rhs \lstinline@|@ \nonterm{identifier} \lstinline@(@ \nonterm{type-name-list} \lstinline@)@ 2983 \rhs \lstinline@|@ \nonterm{spec-declaration} 2982 2984 \lhs{type-name-list} 2983 2985 \rhs \nonterm{type-name} 2984 \rhs \nonterm{type-name-list} \lstinline $,$\nonterm{type-name}2986 \rhs \nonterm{type-name-list} \lstinline@,@ \nonterm{type-name} 2985 2987 \end{syntax} 2986 2988 … … 2989 2991 The \nonterm{type-name-list} shall contain one \nonterm{type-name} argument for each \nonterm{type-parameter} in that specification's \nonterm{spec-parameter-list}. 2990 2992 If the 2991 \nonterm{type-parameter} uses type-class \lstinline $type$\use{type}, the argument shall be the type name of an \Index{object type};2992 if it uses \lstinline $dtype$, the argument shall be the type name of an object type or an \Index{incomplete type};2993 and if it uses \lstinline $ftype$, the argument shall be the type name of a \Index{function type}.2993 \nonterm{type-parameter} uses type-class \lstinline@type@\use{type}, the argument shall be the type name of an \Index{object type}; 2994 if it uses \lstinline@dtype@, the argument shall be the type name of an object type or an \Index{incomplete type}; 2995 and if it uses \lstinline@ftype@, the argument shall be the type name of a \Index{function type}. 2994 2996 2995 2997 \semantics … … 3004 3006 \examples 3005 3007 \begin{lstlisting} 3006 forall( otype T | T ?*?( T, T )) @\use{?*?}@3007 T square( T val ) { @\impl{square}@3008 forall( otype T | T ?*?( T, T ))§\use{?*?}§ 3009 T square( T val ) {§\impl{square}§ 3008 3010 return val + val; 3009 3011 } 3010 trait summable( otype T ) { @\impl{summable}@3011 T ?+=?( T *, T ); @\use{?+=?}@3012 const T 0; @\use{0}@3012 trait summable( otype T ) {§\impl{summable}§ 3013 T ?+=?( T *, T );§\use{?+=?}§ 3014 const T 0;§\use{0}§ 3013 3015 }; 3014 trait list_of( otype List, otype Element ) { @\impl{list_of}@3016 trait list_of( otype List, otype Element ) {§\impl{list_of}§ 3015 3017 Element car( List ); 3016 3018 List cdr( List ); … … 3021 3023 trait sum_list( otype List, otype Element | summable( Element ) | list_of( List, Element ) ) {}; 3022 3024 \end{lstlisting} 3023 \lstinline $sum_list$contains seven declarations, which describe a list whose elements can be added up.3024 The assertion ``\lstinline $|sum_list( i_list, int )$''\use{sum_list} produces the assertion parameters3025 \lstinline@sum_list@ contains seven declarations, which describe a list whose elements can be added up. 3026 The assertion ``\lstinline@|sum_list( i_list, int )@''\use{sum_list} produces the assertion parameters 3025 3027 \begin{lstlisting} 3026 3028 int ?+=?( int *, int ); … … 3039 3041 \lhs{type-parameter-list} 3040 3042 \rhs \nonterm{type-parameter} 3041 \rhs \nonterm{type-parameter-list} \lstinline $,$\nonterm{type-parameter}3043 \rhs \nonterm{type-parameter-list} \lstinline@,@ \nonterm{type-parameter} 3042 3044 \lhs{type-parameter} 3043 3045 \rhs \nonterm{type-class} \nonterm{identifier} \nonterm{assertion-list}\opt 3044 3046 \lhs{type-class} 3045 \rhs \lstinline $type$3046 \rhs \lstinline $dtype$3047 \rhs \lstinline $ftype$3047 \rhs \lstinline@type@ 3048 \rhs \lstinline@dtype@ 3049 \rhs \lstinline@ftype@ 3048 3050 \lhs{type-declaration} 3049 \rhs \nonterm{storage-class-specifier}\opt \lstinline $type$\nonterm{type-declarator-list} \verb|;|3051 \rhs \nonterm{storage-class-specifier}\opt \lstinline@type@ \nonterm{type-declarator-list} \verb|;| 3050 3052 \lhs{type-declarator-list} 3051 3053 \rhs \nonterm{type-declarator} 3052 \rhs \nonterm{type-declarator-list} \lstinline $,$\nonterm{type-declarator}3054 \rhs \nonterm{type-declarator-list} \lstinline@,@ \nonterm{type-declarator} 3053 3055 \lhs{type-declarator} 3054 \rhs \nonterm{identifier} \nonterm{assertion-list}\opt \lstinline $=$\nonterm{type-name}3056 \rhs \nonterm{identifier} \nonterm{assertion-list}\opt \lstinline@=@ \nonterm{type-name} 3055 3057 \rhs \nonterm{identifier} \nonterm{assertion-list}\opt 3056 3058 \end{syntax} … … 3063 3065 3064 3066 An identifier declared by a \nonterm{type-parameter} has \Index{no linkage}. 3065 Identifiers declared with type-class \lstinline $type$\use{type} are \Index{object type}s;3067 Identifiers declared with type-class \lstinline@type@\use{type} are \Index{object type}s; 3066 3068 those declared with type-class 3067 \lstinline $dtype$\use{dtype} are \Index{incomplete type}s;3069 \lstinline@dtype@\use{dtype} are \Index{incomplete type}s; 3068 3070 and those declared with type-class 3069 \lstinline $ftype$\use{ftype} are \Index{function type}s.3071 \lstinline@ftype@\use{ftype} are \Index{function type}s. 3070 3072 The identifier has \Index{block scope} that terminates at the end of the \nonterm{spec-declaration-list} or polymorphic function that contains the \nonterm{type-parameter}. 3071 3073 … … 3075 3077 Within the scope of the declaration, \Index{implicit conversion}s can be performed between the defined type and the implementation type, and between pointers to the defined type and pointers to the implementation type. 3076 3078 3077 A type declaration without an \Index{initializer} and without a \Index{storage-class specifier} or with storage-class specifier \lstinline $static$\use{static} defines an \Index{incomplete type}.3079 A type declaration without an \Index{initializer} and without a \Index{storage-class specifier} or with storage-class specifier \lstinline@static@\use{static} defines an \Index{incomplete type}. 3078 3080 If a 3079 3081 \Index{translation unit} or \Index{block} contains one or more such declarations for an identifier, it must contain exactly one definition of the identifier ( but not in an enclosed block, which would define a new type known only within that block). … … 3095 3097 3096 3098 A type declaration without an initializer and with \Index{storage-class specifier} 3097 \lstinline $extern$\use{extern} is an \define{opaque type declaration}.3099 \lstinline@extern@\use{extern} is an \define{opaque type declaration}. 3098 3100 Opaque types are 3099 3101 \Index{object type}s. … … 3110 3112 \end{rationale} 3111 3113 3112 An \Index{incomplete type} which is not a qualified version\index{qualified type} of a type is a value of \Index{type-class} \lstinline $dtype$.3113 An object type\index{object types} which is not a qualified version of a type is a value of type-classes \lstinline $type$ and \lstinline$dtype$.3114 An \Index{incomplete type} which is not a qualified version\index{qualified type} of a type is a value of \Index{type-class} \lstinline@dtype@. 3115 An object type\index{object types} which is not a qualified version of a type is a value of type-classes \lstinline@type@ and \lstinline@dtype@. 3114 3116 A 3115 \Index{function type} is a value of type-class \lstinline $ftype$.3117 \Index{function type} is a value of type-class \lstinline@ftype@. 3116 3118 \begin{rationale} 3117 3119 Syntactically, a type value is a \nonterm{type-name}, which is a declaration for an object which omits the identifier being declared. … … 3123 3125 Type qualifiers are a weak point of C's type system. 3124 3126 Consider the standard library function 3125 \lstinline $strchr()$which, given a string and a character, returns a pointer to the first occurrence of the character in the string.3126 \begin{lstlisting} 3127 char *strchr( const char *s, int c ) { @\impl{strchr}@3127 \lstinline@strchr()@ which, given a string and a character, returns a pointer to the first occurrence of the character in the string. 3128 \begin{lstlisting} 3129 char *strchr( const char *s, int c ) {§\impl{strchr}§ 3128 3130 char real_c = c; // done because c was declared as int. 3129 3131 for ( ; *s != real_c; s++ ) … … 3132 3134 } 3133 3135 \end{lstlisting} 3134 The parameter \lstinline $s$ must be \lstinline$const char *$, because \lstinline$strchr()$ might be used to search a constant string, but the return type must be \lstinline$char *$, because the result might be used to modify a non-constant string.3136 The parameter \lstinline@s@ must be \lstinline@const char *@, because \lstinline@strchr()@ might be used to search a constant string, but the return type must be \lstinline@char *@, because the result might be used to modify a non-constant string. 3135 3137 Hence the body must perform a cast, and ( even worse) 3136 \lstinline $strchr()$provides a type-safe way to attempt to modify constant strings.3137 What is needed is some way to say that \lstinline $s$'s type might contain qualifiers, and the result type has exactly the same qualifiers.3138 \lstinline@strchr()@ provides a type-safe way to attempt to modify constant strings. 3139 What is needed is some way to say that \lstinline@s@'s type might contain qualifiers, and the result type has exactly the same qualifiers. 3138 3140 Polymorphic functions do not provide a fix for this deficiency\index{deficiencies!pointers to qualified types}, because type qualifiers are not part of type values. 3139 Instead, overloading can be used to define \lstinline $strchr()$for each combination of qualifiers.3141 Instead, overloading can be used to define \lstinline@strchr()@ for each combination of qualifiers. 3140 3142 \end{rationale} 3141 3143 … … 3162 3164 \end{lstlisting} 3163 3165 Without this restriction, \CFA might require ``module initialization'' code ( since 3164 \lstinline $Rational$ has external linkage, it must be created before any other translation unit instantiates it), and would force an ordering on the initialization of the translation unit that defines \lstinline$Huge$ and the translation that declares \lstinline$Rational$.3166 \lstinline@Rational@ has external linkage, it must be created before any other translation unit instantiates it), and would force an ordering on the initialization of the translation unit that defines \lstinline@Huge@ and the translation that declares \lstinline@Rational@. 3165 3167 3166 3168 A benefit of the restriction is that it prevents the declaration in separate translation units of types that contain each other, which would be hard to prevent otherwise. … … 3179 3181 \nonterm{struct-declaration}, type declarations can not be structure members. 3180 3182 The form of 3181 \nonterm{type-declaration} forbids arrays of, pointers to, and functions returning \lstinline $type$.3183 \nonterm{type-declaration} forbids arrays of, pointers to, and functions returning \lstinline@type@. 3182 3184 Hence the syntax of \nonterm{type-specifier} does not have to be extended to allow type-valued expressions. 3183 3185 It also side-steps the problem of type-valued expressions producing different values in different declarations. … … 3194 3196 #include <stdlib.h> 3195 3197 T * new( otype T ) { return ( T * )malloc( sizeof( T) ); }; 3196 @\ldots@int * ip = new( int );3197 \end{lstlisting} 3198 This looks sensible, but \CFA's declaration-before-use rules mean that ``\lstinline $T$'' in the function body refers to the parameter, but the ``\lstinline$T$'' in the return type refers to the meaning of \lstinline$T$ in the scope that contains \lstinline$new$;3198 §\ldots§ int * ip = new( int ); 3199 \end{lstlisting} 3200 This looks sensible, but \CFA's declaration-before-use rules mean that ``\lstinline@T@'' in the function body refers to the parameter, but the ``\lstinline@T@'' in the return type refers to the meaning of \lstinline@T@ in the scope that contains \lstinline@new@; 3199 3201 it could be undefined, or a type name, or a function or variable name. 3200 3202 Nothing good can result from such a situation. … … 3213 3215 f2( v2 ); 3214 3216 \end{lstlisting} 3215 \lstinline $V1$ is passed by value, so \lstinline$f1()$'s assignment to \lstinline$a[0]$ does not modify v1. \lstinline$V2$ is converted to a pointer, so \lstinline$f2()$ modifies \lstinline$v2[0]$.3217 \lstinline@V1@ is passed by value, so \lstinline@f1()@'s assignment to \lstinline@a[0]@ does not modify v1. \lstinline@V2@ is converted to a pointer, so \lstinline@f2()@ modifies \lstinline@v2[0]@. 3216 3218 3217 3219 A translation unit containing the declarations 3218 3220 \begin{lstlisting} 3219 extern type Complex; @\use{Complex}@// opaque type declaration3220 extern float abs( Complex ); @\use{abs}@3221 \end{lstlisting} can contain declarations of complex numbers, which can be passed to \lstinline $abs$.3222 Some other translation unit must implement \lstinline $Complex$ and \lstinline$abs$.3221 extern type Complex;§\use{Complex}§ // opaque type declaration 3222 extern float abs( Complex );§\use{abs}§ 3223 \end{lstlisting} can contain declarations of complex numbers, which can be passed to \lstinline@abs@. 3224 Some other translation unit must implement \lstinline@Complex@ and \lstinline@abs@. 3223 3225 That unit might contain the declarations 3224 3226 \begin{lstlisting} 3225 otype Complex = struct { float re, im; }; @\impl{Complex}@3226 Complex cplx_i = { 0.0, 1.0 }; @\impl{cplx_i}@3227 float abs( Complex c ) { @\impl{abs( Complex )}@3227 otype Complex = struct { float re, im; };§\impl{Complex}§ 3228 Complex cplx_i = { 0.0, 1.0 };§\impl{cplx_i}§ 3229 float abs( Complex c ) {§\impl{abs( Complex )}§ 3228 3230 return sqrt( c.re * c.re + c.im * c.im ); 3229 3231 } 3230 3232 \end{lstlisting} 3231 Note that \lstinline $c$ is implicitly converted to a \lstinline$struct$so that its components can be retrieved.3232 3233 \begin{lstlisting} 3234 otype Time_of_day = int; @\impl{Time_of_day}@// seconds since midnight.3235 Time_of_day ?+?( Time_of_day t1, int seconds ) { @\impl{?+?}@3233 Note that \lstinline@c@ is implicitly converted to a \lstinline@struct@ so that its components can be retrieved. 3234 3235 \begin{lstlisting} 3236 otype Time_of_day = int;§\impl{Time_of_day}§ // seconds since midnight. 3237 Time_of_day ?+?( Time_of_day t1, int seconds ) {§\impl{?+?}§ 3236 3238 return (( int)t1 + seconds ) % 86400; 3237 3239 } 3238 3240 \end{lstlisting} 3239 \lstinline $t1$must be cast to its implementation type to prevent infinite recursion.3241 \lstinline@t1@ must be cast to its implementation type to prevent infinite recursion. 3240 3242 3241 3243 \begin{rationale} 3242 3244 Within the scope of a type definition, an instance of the type can be viewed as having that type or as having the implementation type. 3243 In the \lstinline $Time_of_day$example, the difference is important.3245 In the \lstinline@Time_of_day@ example, the difference is important. 3244 3246 Different languages have treated the distinction between the abstraction and the implementation in different ways. 3245 3247 \begin{itemize} 3246 3248 \item 3247 3249 Inside a Clu cluster \cite{CLU}, the declaration of an instance states which view applies. 3248 Two primitives called \lstinline $up$ and \lstinline$down$can be used to convert between the views.3250 Two primitives called \lstinline@up@ and \lstinline@down@ can be used to convert between the views. 3249 3251 \item 3250 3252 The Simula class \cite{SIMULA87} is essentially a record type. 3251 3253 Since the only operations on a record are member selection and assignment, which can not be overloaded, there is never any ambiguity as to whether the abstraction or the implementation view is being used. 3252 3254 In {\CC} 3253 \cite{C++}, operations on class instances include assignment and ``\lstinline $&$'', which can be overloaded.3255 \cite{C++}, operations on class instances include assignment and ``\lstinline@&@'', which can be overloaded. 3254 3256 A ``scope resolution'' operator can be used inside the class to specify whether the abstract or implementation version of the operation should be used. 3255 3257 \item … … 3264 3266 In this case, explicit conversions between the derived type and the old type can be used. 3265 3267 \end{itemize} 3266 \CFA's rules are like Clu's, except that implicit conversions and conversion costs allow it to do away with most uses of \lstinline $up$ and \lstinline$down$.3268 \CFA's rules are like Clu's, except that implicit conversions and conversion costs allow it to do away with most uses of \lstinline@up@ and \lstinline@down@. 3267 3269 \end{rationale} 3268 3270 … … 3270 3272 \subsubsection{Default functions and objects} 3271 3273 3272 A declaration\index{type declaration} of a type identifier \lstinline $T$with type-class3273 \lstinline $type$implicitly declares a \define{default assignment} function3274 \lstinline $T ?=?( T *, T )$\use{?=?}, with the same \Index{scope} and \Index{linkage} as the identifier \lstinline$T$.3274 A declaration\index{type declaration} of a type identifier \lstinline@T@ with type-class 3275 \lstinline@type@ implicitly declares a \define{default assignment} function 3276 \lstinline@T ?=?( T *, T )@\use{?=?}, with the same \Index{scope} and \Index{linkage} as the identifier \lstinline@T@. 3275 3277 \begin{rationale} 3276 3278 Assignment is central to C's imperative programming style, and every existing C object type has assignment defined for it ( except for array types, which are treated as pointer types for purposes of assignment). 3277 3279 Without this rule, nearly every inferred type parameter would need an accompanying assignment assertion parameter. 3278 3280 If a type parameter should not have an assignment operation, 3279 \lstinline $dtype$should be used.3281 \lstinline@dtype@ should be used. 3280 3282 If a type should not have assignment defined, the user can define an assignment function that causes a run-time error, or provide an external declaration but no definition and thus cause a link-time error. 3281 3283 \end{rationale} 3282 3284 3283 A definition\index{type definition} of a type identifier \lstinline $T$ with \Index{implementation type} \lstinline$I$ and type-class \lstinline$type$implicitly defines a default assignment function.3284 A definition\index{type definition} of a type identifier \lstinline $T$ with implementation type \lstinline$I$and an assertion list implicitly defines \define{default function}s and3285 A definition\index{type definition} of a type identifier \lstinline@T@ with \Index{implementation type} \lstinline@I@ and type-class \lstinline@type@ implicitly defines a default assignment function. 3286 A definition\index{type definition} of a type identifier \lstinline@T@ with implementation type \lstinline@I@ and an assertion list implicitly defines \define{default function}s and 3285 3287 \define{default object}s as declared by the assertion declarations. 3286 The default objects and functions have the same \Index{scope} and \Index{linkage} as the identifier \lstinline $T$.3288 The default objects and functions have the same \Index{scope} and \Index{linkage} as the identifier \lstinline@T@. 3287 3289 Their values are determined as follows: 3288 3290 \begin{itemize} 3289 3291 \item 3290 If at the definition of \lstinline $T$ there is visible a declaration of an object with the same name as the default object, and if the type of that object with all occurrence of \lstinline$I$ replaced by \lstinline$T$is compatible with the type of the default object, then the default object is initialized with that object.3291 Otherwise the scope of the declaration of \lstinline $T$must contain a definition of the default object.3292 If at the definition of \lstinline@T@ there is visible a declaration of an object with the same name as the default object, and if the type of that object with all occurrence of \lstinline@I@ replaced by \lstinline@T@ is compatible with the type of the default object, then the default object is initialized with that object. 3293 Otherwise the scope of the declaration of \lstinline@T@ must contain a definition of the default object. 3292 3294 3293 3295 \item 3294 If at the definition of \lstinline $T$ there is visible a declaration of a function with the same name as the default function, and if the type of that function with all occurrence of \lstinline$I$ replaced by \lstinline$T$is compatible with the type of the default function, then the default function calls that function after converting its arguments and returns the converted result.3295 3296 Otherwise, if \lstinline $I$ contains exactly one anonymous member\index{anonymous member} such that at the definition of \lstinline$T$ there is visible a declaration of a function with the same name as the default function, and the type of that function with all occurrences of the anonymous member's type in its parameter list replaced by \lstinline$T$is compatible with the type of the default function, then the default function calls that function after converting its arguments and returns the result.3297 3298 Otherwise the scope of the declaration of \lstinline $T$must contain a definition of the default function.3296 If at the definition of \lstinline@T@ there is visible a declaration of a function with the same name as the default function, and if the type of that function with all occurrence of \lstinline@I@ replaced by \lstinline@T@ is compatible with the type of the default function, then the default function calls that function after converting its arguments and returns the converted result. 3297 3298 Otherwise, if \lstinline@I@ contains exactly one anonymous member\index{anonymous member} such that at the definition of \lstinline@T@ there is visible a declaration of a function with the same name as the default function, and the type of that function with all occurrences of the anonymous member's type in its parameter list replaced by \lstinline@T@ is compatible with the type of the default function, then the default function calls that function after converting its arguments and returns the result. 3299 3300 Otherwise the scope of the declaration of \lstinline@T@ must contain a definition of the default function. 3299 3301 \end{itemize} 3300 3302 \begin{rationale} … … 3302 3304 \end{rationale} 3303 3305 3304 A function or object with the same type and name as a default function or object that is declared within the scope of the definition of \lstinline $T$replaces the default function or object.3306 A function or object with the same type and name as a default function or object that is declared within the scope of the definition of \lstinline@T@ replaces the default function or object. 3305 3307 3306 3308 \examples … … 3312 3314 Pair b = { 1, 1 }; 3313 3315 \end{lstlisting} 3314 The definition of \lstinline $Pair$ implicitly defines two objects \lstinline$a$ and \lstinline$b$.3315 \lstinline $Pair a$ inherits its value from the \lstinline$struct impl a$.3316 The definition of \lstinline@Pair@ implicitly defines two objects \lstinline@a@ and \lstinline@b@. 3317 \lstinline@Pair a@ inherits its value from the \lstinline@struct impl a@. 3316 3318 The definition of 3317 \lstinline $Pair b$ is compulsory because there is no \lstinline$struct impl b$to construct a value from.3319 \lstinline@Pair b@ is compulsory because there is no \lstinline@struct impl b@ to construct a value from. 3318 3320 \begin{lstlisting} 3319 3321 trait ss( otype T ) { … … 3321 3323 void munge( T * ); 3322 3324 } 3323 otype Whatsit | ss( Whatsit ); @\use{Whatsit}@3324 otype Doodad | ss( Doodad ) = struct doodad { @\use{Doodad}@3325 otype Whatsit | ss( Whatsit );§\use{Whatsit}§ 3326 otype Doodad | ss( Doodad ) = struct doodad {§\use{Doodad}§ 3325 3327 Whatsit; // anonymous member 3326 3328 int extra; … … 3328 3330 Doodad clone( Doodad ) { ... } 3329 3331 \end{lstlisting} 3330 The definition of \lstinline $Doodad$implicitly defines three functions:3332 The definition of \lstinline@Doodad@ implicitly defines three functions: 3331 3333 \begin{lstlisting} 3332 3334 Doodad ?=?( Doodad *, Doodad ); … … 3334 3336 void munge( Doodad * ); 3335 3337 \end{lstlisting} 3336 The assignment function inherits \lstinline $struct doodad$'s assignment function because the types match when \lstinline$struct doodad$ is replaced by \lstinline$Doodad$throughout.3337 \lstinline $munge()$ inherits \lstinline$Whatsit$'s \lstinline$munge()$because the types match when3338 \lstinline $Whatsit$ is replaced by \lstinline$Doodad$ in the parameter list. \lstinline$clone()$ does \emph{not} inherit \lstinline$Whatsit$'s \lstinline$clone()$: replacement in the parameter list yields ``\lstinline$Whatsit clone( Doodad )$'', which is not compatible with3339 \lstinline $Doodad$'s \lstinline$clone()$'s type.3338 The assignment function inherits \lstinline@struct doodad@'s assignment function because the types match when \lstinline@struct doodad@ is replaced by \lstinline@Doodad@ throughout. 3339 \lstinline@munge()@ inherits \lstinline@Whatsit@'s \lstinline@munge()@ because the types match when 3340 \lstinline@Whatsit@ is replaced by \lstinline@Doodad@ in the parameter list. \lstinline@clone()@ does \emph{not} inherit \lstinline@Whatsit@'s \lstinline@clone()@: replacement in the parameter list yields ``\lstinline@Whatsit clone( Doodad )@'', which is not compatible with 3341 \lstinline@Doodad@'s \lstinline@clone()@'s type. 3340 3342 Hence the definition of 3341 ``\lstinline $Doodad clone( Doodad )$'' is necessary.3343 ``\lstinline@Doodad clone( Doodad )@'' is necessary. 3342 3344 3343 3345 Default functions and objects are subject to the normal scope rules. 3344 3346 \begin{lstlisting} 3345 otype T = @\ldots@;3346 T a_T = @\ldots@; // Default assignment used.3347 otype T = §\ldots§; 3348 T a_T = §\ldots§; // Default assignment used. 3347 3349 T ?=?( T *, T ); 3348 T a_T = @\ldots@; // Programmer-defined assignment called.3350 T a_T = §\ldots§; // Programmer-defined assignment called. 3349 3351 \end{lstlisting} 3350 3352 \begin{rationale} … … 3379 3381 \begin{syntax} 3380 3382 \oldlhs{labeled-statement} 3381 \rhs \lstinline $case$\nonterm{case-value-list} : \nonterm{statement}3383 \rhs \lstinline@case@ \nonterm{case-value-list} : \nonterm{statement} 3382 3384 \lhs{case-value-list} 3383 3385 \rhs \nonterm{case-value} 3384 \rhs \nonterm{case-value-list} \lstinline $,$\nonterm{case-value}3386 \rhs \nonterm{case-value-list} \lstinline@,@ \nonterm{case-value} 3385 3387 \lhs{case-value} 3386 3388 \rhs \nonterm{constant-expression} 3387 3389 \rhs \nonterm{subrange} 3388 3390 \lhs{subrange} 3389 \rhs \nonterm{constant-expression} \lstinline $~$\nonterm{constant-expression}3391 \rhs \nonterm{constant-expression} \lstinline@~@ \nonterm{constant-expression} 3390 3392 \end{syntax} 3391 3393 … … 3400 3402 case 1~4, 9~14, 27~32: 3401 3403 \end{lstlisting} 3402 The \lstinline $case$ and \lstinline$default$ clauses are restricted within the \lstinline$switch$ and \lstinline$choose$statements, precluding Duff's device.3404 The \lstinline@case@ and \lstinline@default@ clauses are restricted within the \lstinline@switch@ and \lstinline@choose@ statements, precluding Duff's device. 3403 3405 3404 3406 3405 3407 \subsection{Expression and null statements} 3406 3408 3407 The expression in an expression statement is treated as being cast to \lstinline $void$.3409 The expression in an expression statement is treated as being cast to \lstinline@void@. 3408 3410 3409 3411 … … 3412 3414 \begin{syntax} 3413 3415 \oldlhs{selection-statement} 3414 \rhs \lstinline $choose$ \lstinline$($ \nonterm{expression} \lstinline$)$\nonterm{statement}3416 \rhs \lstinline@choose@ \lstinline@(@ \nonterm{expression} \lstinline@)@ \nonterm{statement} 3415 3417 \end{syntax} 3416 3418 3417 The controlling expression \lstinline $E$ in the \lstinline$switch$ and \lstinline$choose$statement:3419 The controlling expression \lstinline@E@ in the \lstinline@switch@ and \lstinline@choose@ statement: 3418 3420 \begin{lstlisting} 3419 3421 switch ( E ) ... … … 3421 3423 \end{lstlisting} may have more than one interpretation, but it shall have only one interpretation with an integral type. 3422 3424 An \Index{integer promotion} is performed on the expression if necessary. 3423 The constant expressions in \lstinline $case$statements with the switch are converted to the promoted type.3425 The constant expressions in \lstinline@case@ statements with the switch are converted to the promoted type. 3424 3426 3425 3427 3426 3428 \setcounter{subsubsection}{3} 3427 \subsubsection {The \lstinline$choose$statement}3428 3429 The \lstinline $choose$ statement is the same as the \lstinline$switch$ statement except control transfers to the end of the \lstinline$choose$ statement at a \lstinline$case$ or \lstinline$default$labeled statement.3430 The \lstinline $fallthru$ statement is used to fall through to the next \lstinline$case$ or \lstinline$default$labeled statement.3429 \subsubsection[The choose statement]{The \lstinline@choose@ statement} 3430 3431 The \lstinline@choose@ statement is the same as the \lstinline@switch@ statement except control transfers to the end of the \lstinline@choose@ statement at a \lstinline@case@ or \lstinline@default@ labeled statement. 3432 The \lstinline@fallthru@ statement is used to fall through to the next \lstinline@case@ or \lstinline@default@ labeled statement. 3431 3433 The following have identical meaning: 3432 3434 \begin{flushleft} … … 3453 3455 \end{tabular} 3454 3456 \end{flushleft} 3455 The \lstinline $choose$ statement addresses the problem of accidental fall-through associated with the \lstinline$switch$statement.3457 The \lstinline@choose@ statement addresses the problem of accidental fall-through associated with the \lstinline@switch@ statement. 3456 3458 3457 3459 3458 3460 \subsection{Iteration statements} 3459 3461 3460 The controlling expression \lstinline $E$in the loops3462 The controlling expression \lstinline@E@ in the loops 3461 3463 \begin{lstlisting} 3462 3464 if ( E ) ... 3463 3465 while ( E ) ... 3464 3466 do ... while ( E ); 3465 \end{lstlisting} is treated as ``\lstinline $( int )((E)!=0)$''.3467 \end{lstlisting} is treated as ``\lstinline@( int )((E)!=0)@''. 3466 3468 3467 3469 The statement 3468 3470 \begin{lstlisting} 3469 for ( a; b; c ) @\ldots@3471 for ( a; b; c ) §\ldots§ 3470 3472 \end{lstlisting} is treated as 3471 3473 \begin{lstlisting} … … 3478 3480 \begin{syntax} 3479 3481 \oldlhs{jump-statement} 3480 \rhs \lstinline $continue$\nonterm{identifier}\opt3481 \rhs \lstinline $break$\nonterm{identifier}\opt3482 \rhs \lstinline@continue@ \nonterm{identifier}\opt 3483 \rhs \lstinline@break@ \nonterm{identifier}\opt 3482 3484 \rhs \ldots 3483 \rhs \lstinline $throw$\nonterm{assignment-expression}\opt3484 \rhs \lstinline $throwResume$\nonterm{assignment-expression}\opt \nonterm{at-expression}\opt3485 \lhs{at-expression} \lstinline $_At$\nonterm{assignment-expression}3485 \rhs \lstinline@throw@ \nonterm{assignment-expression}\opt 3486 \rhs \lstinline@throwResume@ \nonterm{assignment-expression}\opt \nonterm{at-expression}\opt 3487 \lhs{at-expression} \lstinline@_At@ \nonterm{assignment-expression} 3486 3488 \end{syntax} 3487 3489 3488 Labeled \lstinline $continue$ and \lstinline$break$ allow useful but restricted control-flow that reduces the need for the \lstinline$goto$statement for exiting multiple nested control-structures.3490 Labeled \lstinline@continue@ and \lstinline@break@ allow useful but restricted control-flow that reduces the need for the \lstinline@goto@ statement for exiting multiple nested control-structures. 3489 3491 \begin{lstlisting} 3490 3492 L1: { // compound … … 3513 3515 3514 3516 \setcounter{subsubsection}{1} 3515 \subsubsection {The \lstinline$continue$statement}3516 3517 The identifier in a \lstinline $continue$statement shall name a label located on an enclosing iteration statement.3518 3519 3520 \subsubsection {The \lstinline$break$statement}3521 3522 The identifier in a \lstinline $break$statement shall name a label located on an enclosing compound, selection or iteration statement.3523 3524 3525 \subsubsection {The \lstinline$return$statement}3526 3527 An expression in a \lstinline $return$statement is treated as being cast to the result type of the function.3528 3529 3530 \subsubsection {The \lstinline$throw$statement}3517 \subsubsection[The continue statement]{The \lstinline@continue@ statement} 3518 3519 The identifier in a \lstinline@continue@ statement shall name a label located on an enclosing iteration statement. 3520 3521 3522 \subsubsection[The break statement]{The \lstinline@break@ statement} 3523 3524 The identifier in a \lstinline@break@ statement shall name a label located on an enclosing compound, selection or iteration statement. 3525 3526 3527 \subsubsection[The return statement]{The \lstinline@return@ statement} 3528 3529 An expression in a \lstinline@return@ statement is treated as being cast to the result type of the function. 3530 3531 3532 \subsubsection[The throw statement]{The \lstinline@throw@ statement} 3531 3533 3532 3534 When an exception is raised, \Index{propagation} directs control from a raise in the source execution to a handler in the faulting execution. 3533 3535 3534 3536 3535 \subsubsection {The \lstinline$throwResume$statement}3537 \subsubsection[The throwResume statement]{The \lstinline@throwResume@ statement} 3536 3538 3537 3539 … … 3540 3542 \begin{syntax} 3541 3543 \lhs{exception-statement} 3542 \rhs \lstinline $try$\nonterm{compound-statement} \nonterm{handler-list}3543 \rhs \lstinline $try$\nonterm{compound-statement} \nonterm{finally-clause}3544 \rhs \lstinline $try$\nonterm{compound-statement} \nonterm{handler-list} \nonterm{finally-clause}3544 \rhs \lstinline@try@ \nonterm{compound-statement} \nonterm{handler-list} 3545 \rhs \lstinline@try@ \nonterm{compound-statement} \nonterm{finally-clause} 3546 \rhs \lstinline@try@ \nonterm{compound-statement} \nonterm{handler-list} \nonterm{finally-clause} 3545 3547 \lhs{handler-list} 3546 3548 \rhs \nonterm{handler-clause} 3547 \rhs \lstinline $catch$ \lstinline$($ \ldots \lstinline$)$\nonterm{compound-statement}3548 \rhs \nonterm{handler-clause} \lstinline $catch$ \lstinline$($ \ldots \lstinline$)$\nonterm{compound-statement}3549 \rhs \lstinline $catchResume$ \lstinline$($ \ldots \lstinline$)$\nonterm{compound-statement}3550 \rhs \nonterm{handler-clause} \lstinline $catchResume$ \lstinline$($ \ldots \lstinline$)$\nonterm{compound-statement}3549 \rhs \lstinline@catch@ \lstinline@(@ \ldots \lstinline@)@ \nonterm{compound-statement} 3550 \rhs \nonterm{handler-clause} \lstinline@catch@ \lstinline@(@ \ldots \lstinline@)@ \nonterm{compound-statement} 3551 \rhs \lstinline@catchResume@ \lstinline@(@ \ldots \lstinline@)@ \nonterm{compound-statement} 3552 \rhs \nonterm{handler-clause} \lstinline@catchResume@ \lstinline@(@ \ldots \lstinline@)@ \nonterm{compound-statement} 3551 3553 \lhs{handler-clause} 3552 \rhs \lstinline $catch$ \lstinline$($ \nonterm{exception-declaration} \lstinline$)$\nonterm{compound-statement}3553 \rhs \nonterm{handler-clause} \lstinline $catch$ \lstinline$($ \nonterm{exception-declaration} \lstinline$)$\nonterm{compound-statement}3554 \rhs \lstinline $catchResume$ \lstinline$($ \nonterm{exception-declaration} \lstinline$)$\nonterm{compound-statement}3555 \rhs \nonterm{handler-clause} \lstinline $catchResume$ \lstinline$($ \nonterm{exception-declaration} \lstinline$)$\nonterm{compound-statement}3554 \rhs \lstinline@catch@ \lstinline@(@ \nonterm{exception-declaration} \lstinline@)@ \nonterm{compound-statement} 3555 \rhs \nonterm{handler-clause} \lstinline@catch@ \lstinline@(@ \nonterm{exception-declaration} \lstinline@)@ \nonterm{compound-statement} 3556 \rhs \lstinline@catchResume@ \lstinline@(@ \nonterm{exception-declaration} \lstinline@)@ \nonterm{compound-statement} 3557 \rhs \nonterm{handler-clause} \lstinline@catchResume@ \lstinline@(@ \nonterm{exception-declaration} \lstinline@)@ \nonterm{compound-statement} 3556 3558 \lhs{finally-clause} 3557 \rhs \lstinline $finally$\nonterm{compound-statement}3559 \rhs \lstinline@finally@ \nonterm{compound-statement} 3558 3560 \lhs{exception-declaration} 3559 3561 \rhs \nonterm{type-specifier} … … 3563 3565 \rhs \nonterm{new-abstract-declarator-tuple} 3564 3566 \lhs{asynchronous-statement} 3565 \rhs \lstinline $enable$\nonterm{identifier-list} \nonterm{compound-statement}3566 \rhs \lstinline $disable$\nonterm{identifier-list} \nonterm{compound-statement}3567 \rhs \lstinline@enable@ \nonterm{identifier-list} \nonterm{compound-statement} 3568 \rhs \lstinline@disable@ \nonterm{identifier-list} \nonterm{compound-statement} 3567 3569 \end{syntax} 3568 3570 … … 3570 3572 3571 3573 3572 \subsubsection {The \lstinline$try$statement}3573 3574 The \lstinline $try$statement is a block with associated handlers, called a \Index{guarded block};3574 \subsubsection[The try statement]{The \lstinline@try@ statement} 3575 3576 The \lstinline@try@ statement is a block with associated handlers, called a \Index{guarded block}; 3575 3577 all other blocks are \Index{unguarded block}s. 3576 A \lstinline $goto$, \lstinline$break$, \lstinline$return$, or \lstinline$continue$statement can be used to transfer control out of a try block or handler, but not into one.3577 3578 3579 \subsubsection {The \lstinline$enable$/\lstinline$disable$statements}3580 3581 The \lstinline $enable$/\lstinline$disable$statements toggle delivery of \Index{asynchronous exception}s.3578 A \lstinline@goto@, \lstinline@break@, \lstinline@return@, or \lstinline@continue@ statement can be used to transfer control out of a try block or handler, but not into one. 3579 3580 3581 \subsubsection[The enable/disable statements]{The \lstinline@enable@/\lstinline@disable@ statements} 3582 3583 The \lstinline@enable@/\lstinline@disable@ statements toggle delivery of \Index{asynchronous exception}s. 3582 3584 3583 3585 … … 3589 3591 \subsection{Predefined macro names} 3590 3592 3591 The implementation shall define the macro names \lstinline $__LINE__$, \lstinline$__FILE__$,3592 \lstinline $__DATE__$, and \lstinline$__TIME__$, as in the {\c11} standard.3593 It shall not define the macro name \lstinline $__STDC__$.3594 3595 In addition, the implementation shall define the macro name \lstinline $__CFORALL__$to be the decimal constant 1.3593 The implementation shall define the macro names \lstinline@__LINE__@, \lstinline@__FILE__@, 3594 \lstinline@__DATE__@, and \lstinline@__TIME__@, as in the {\c11} standard. 3595 It shall not define the macro name \lstinline@__STDC__@. 3596 3597 In addition, the implementation shall define the macro name \lstinline@__CFORALL__@ to be the decimal constant 1. 3596 3598 3597 3599 … … 3610 3612 The pointer, integral, and floating-point types are all \define{scalar types}. 3611 3613 All of these types can be logically negated and compared. 3612 The assertion ``\lstinline $scalar( Complex )$'' should be read as ``type \lstinline$Complex$is scalar''.3613 \begin{lstlisting} 3614 trait scalar( otype T ) { @\impl{scalar}@3614 The assertion ``\lstinline@scalar( Complex )@'' should be read as ``type \lstinline@Complex@ is scalar''. 3615 \begin{lstlisting} 3616 trait scalar( otype T ) {§\impl{scalar}§ 3615 3617 int !?( T ); 3616 3618 int ?<?( T, T ), ?<=?( T, T ), ?==?( T, T ), ?>=?( T, T ), ?>?( T, T ), ?!=?( T, T ); … … 3622 3624 This is equivalent to inheritance of specifications. 3623 3625 \begin{lstlisting} 3624 trait arithmetic( otype T | scalar( T ) ) { @\impl{arithmetic}@@\use{scalar}@3626 trait arithmetic( otype T | scalar( T ) ) {§\impl{arithmetic}§§\use{scalar}§ 3625 3627 T +?( T ), -?( T ); 3626 3628 T ?*?( T, T ), ?/?( T, T ), ?+?( T, T ), ?-?( T, T ); … … 3628 3630 \end{lstlisting} 3629 3631 3630 The various flavors of \lstinline $char$ and \lstinline$int$and the enumerated types make up the3632 The various flavors of \lstinline@char@ and \lstinline@int@ and the enumerated types make up the 3631 3633 \define{integral types}. 3632 3634 \begin{lstlisting} 3633 trait integral( otype T | arithmetic( T ) ) { @\impl{integral}@@\use{arithmetic}@3635 trait integral( otype T | arithmetic( T ) ) {§\impl{integral}§§\use{arithmetic}§ 3634 3636 T ~?( T ); 3635 3637 T ?&?( T, T ), ?|?( T, T ), ?^?( T, T ); … … 3645 3647 The only operation that can be applied to all modifiable lvalues is simple assignment. 3646 3648 \begin{lstlisting} 3647 trait m_lvalue( otype T ) { @\impl{m_lvalue}@3649 trait m_lvalue( otype T ) {§\impl{m_lvalue}§ 3648 3650 T ?=?( T *, T ); 3649 3651 }; … … 3655 3657 Scalars can also be incremented and decremented. 3656 3658 \begin{lstlisting} 3657 trait m_l_scalar( otype T | scalar( T ) | m_lvalue( T ) ) { @\impl{m_l_scalar}@3658 T ?++( T * ), ?--( T * ); @\use{scalar}@@\use{m_lvalue}@3659 trait m_l_scalar( otype T | scalar( T ) | m_lvalue( T ) ) {§\impl{m_l_scalar}§ 3660 T ?++( T * ), ?--( T * );§\use{scalar}§§\use{m_lvalue}§ 3659 3661 T ++?( T * ), --?( T * ); 3660 3662 }; … … 3662 3664 3663 3665 Modifiable arithmetic lvalues are both modifiable scalar lvalues and arithmetic. 3664 Note that this results in the ``inheritance'' of \lstinline $scalar$along both paths.3665 \begin{lstlisting} 3666 trait m_l_arithmetic( otype T | m_l_scalar( T ) | arithmetic( T ) ) { @\impl{m_l_arithmetic}@3667 T ?/=?( T *, T ), ?*=?( T *, T ); @\use{m_l_scalar}@@\use{arithmetic}@3666 Note that this results in the ``inheritance'' of \lstinline@scalar@ along both paths. 3667 \begin{lstlisting} 3668 trait m_l_arithmetic( otype T | m_l_scalar( T ) | arithmetic( T ) ) {§\impl{m_l_arithmetic}§ 3669 T ?/=?( T *, T ), ?*=?( T *, T );§\use{m_l_scalar}§§\use{arithmetic}§ 3668 3670 T ?+=?( T *, T ), ?-=?( T *, T ); 3669 3671 }; 3670 trait m_l_integral( otype T | m_l_arithmetic( T ) | integral( T ) ) { @\impl{m_l_integral}@3671 T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T ); @\use{m_l_arithmetic}@3672 T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T ); @\use{integral}@3672 trait m_l_integral( otype T | m_l_arithmetic( T ) | integral( T ) ) {§\impl{m_l_integral}§ 3673 T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T );§\use{m_l_arithmetic}§ 3674 T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T );§\use{integral}§ 3673 3675 }; 3674 3676 \end{lstlisting} … … 3678 3680 3679 3681 Array types can barely be said to exist in {\c11}, since in most cases an array name is treated as a constant pointer to the first element of the array, and the subscript expression 3680 ``\lstinline $a[i]$'' is equivalent to the dereferencing expression ``\lstinline$(*( a+( i )))$''.3681 Technically, pointer arithmetic and pointer comparisons other than ``\lstinline $==$'' and3682 ``\lstinline $!=$'' are only defined for pointers to array elements, but the type system does not enforce those restrictions.3682 ``\lstinline@a[i]@'' is equivalent to the dereferencing expression ``\lstinline@(*( a+( i )))@''. 3683 Technically, pointer arithmetic and pointer comparisons other than ``\lstinline@==@'' and 3684 ``\lstinline@!=@'' are only defined for pointers to array elements, but the type system does not enforce those restrictions. 3683 3685 Consequently, there is no need for a separate ``array type'' specification. 3684 3686 3685 3687 Pointer types are scalar types. 3686 Like other scalar types, they have ``\lstinline $+$'' and3687 ``\lstinline $-$'' operators, but the types do not match the types of the operations in3688 \lstinline $arithmetic$, so these operators cannot be consolidated in \lstinline$scalar$.3689 \begin{lstlisting} 3690 trait pointer( type P | scalar( P ) ) { @\impl{pointer}@@\use{scalar}@3688 Like other scalar types, they have ``\lstinline@+@'' and 3689 ``\lstinline@-@'' operators, but the types do not match the types of the operations in 3690 \lstinline@arithmetic@, so these operators cannot be consolidated in \lstinline@scalar@. 3691 \begin{lstlisting} 3692 trait pointer( type P | scalar( P ) ) {§\impl{pointer}§§\use{scalar}§ 3691 3693 P ?+?( P, long int ), ?+?( long int, P ), ?-?( P, long int ); 3692 3694 ptrdiff_t ?-?( P, P ); 3693 3695 }; 3694 trait m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) { @\impl{m_l_pointer}@3696 trait m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {§\impl{m_l_pointer}§ 3695 3697 P ?+=?( P *, long int ), ?-=?( P *, long int ); 3696 3698 P ?=?( P *, void * ); … … 3701 3703 Specifications that define the dereference operator ( or subscript operator ) require two parameters, one for the pointer type and one for the pointed-at ( or element ) type. 3702 3704 Different specifications are needed for each set of \Index{type qualifier}s, because qualifiers are not included in types. 3703 The assertion ``\lstinline $|ptr_to( Safe_pointer, int )$'' should be read as3704 ``\lstinline $Safe_pointer$ acts like a pointer to \lstinline$int$''.3705 \begin{lstlisting} 3706 trait ptr_to( otype P | pointer( P ), otype T ) { @\impl{ptr_to}@@\use{pointer}@3705 The assertion ``\lstinline@|ptr_to( Safe_pointer, int )@'' should be read as 3706 ``\lstinline@Safe_pointer@ acts like a pointer to \lstinline@int@''. 3707 \begin{lstlisting} 3708 trait ptr_to( otype P | pointer( P ), otype T ) {§\impl{ptr_to}§§\use{pointer}§ 3707 3709 lvalue T *?( P ); 3708 3710 lvalue T ?[?]( P, long int ); 3709 3711 }; 3710 trait ptr_to_const( otype P | pointer( P ), otype T ) { @\impl{ptr_to_const}@3712 trait ptr_to_const( otype P | pointer( P ), otype T ) {§\impl{ptr_to_const}§ 3711 3713 const lvalue T *?( P ); 3712 const lvalue T ?[?]( P, long int ); @\use{pointer}@3714 const lvalue T ?[?]( P, long int );§\use{pointer}§ 3713 3715 }; 3714 trait ptr_to_volatile( otype P | pointer( P ), otype T ) } @\impl{ptr_to_volatile}@3716 trait ptr_to_volatile( otype P | pointer( P ), otype T ) }§\impl{ptr_to_volatile}§ 3715 3717 volatile lvalue T *?( P ); 3716 volatile lvalue T ?[?]( P, long int ); @\use{pointer}@3718 volatile lvalue T ?[?]( P, long int );§\use{pointer}§ 3717 3719 }; 3718 trait ptr_to_const_volatile( otype P | pointer( P ), otype T ) } @\impl{ptr_to_const_volatile}@3719 const volatile lvalue T *?( P ); @\use{pointer}@3720 trait ptr_to_const_volatile( otype P | pointer( P ), otype T ) }§\impl{ptr_to_const_volatile}§ 3721 const volatile lvalue T *?( P );§\use{pointer}§ 3720 3722 const volatile lvalue T ?[?]( P, long int ); 3721 3723 }; 3722 3724 \end{lstlisting} 3723 3725 3724 Assignment to pointers is more complicated than is the case with other types, because the target's type can have extra type qualifiers in the pointed-at type: a ``\lstinline $T *$'' can be assigned to a ``\lstinline$const T *$'', a ``\lstinline$volatile T *$'', and a ``\lstinline$const volatile T *$''.3726 Assignment to pointers is more complicated than is the case with other types, because the target's type can have extra type qualifiers in the pointed-at type: a ``\lstinline@T *@'' can be assigned to a ``\lstinline@const T *@'', a ``\lstinline@volatile T *@'', and a ``\lstinline@const volatile T *@''. 3725 3727 Again, the pointed-at type is passed in, so that assertions can connect these specifications to the 3726 ``\lstinline $ptr_to$'' specifications.3727 \begin{lstlisting} 3728 trait m_l_ptr_to( otype P | m_l_pointer( P ), @\use{m_l_pointer}@@\impl{m_l_ptr_to}@ otype T | ptr_to( P, T )@\use{ptr_to}@{3728 ``\lstinline@ptr_to@'' specifications. 3729 \begin{lstlisting} 3730 trait m_l_ptr_to( otype P | m_l_pointer( P ),§\use{m_l_pointer}§§\impl{m_l_ptr_to}§ otype T | ptr_to( P, T )§\use{ptr_to}§ { 3729 3731 P ?=?( P *, T * ); 3730 3732 T * ?=?( T **, P ); 3731 3733 }; 3732 trait m_l_ptr_to_const( otype P | m_l_pointer( P ), @\use{m_l_pointer}@@\impl{m_l_ptr_to_const}@ otype T | ptr_to_const( P, T )@\use{ptr_to_const}@) {3734 trait m_l_ptr_to_const( otype P | m_l_pointer( P ),§\use{m_l_pointer}§§\impl{m_l_ptr_to_const}§ otype T | ptr_to_const( P, T )§\use{ptr_to_const}§) { 3733 3735 P ?=?( P *, const T * ); 3734 3736 const T * ?=?( const T **, P ); 3735 3737 }; 3736 trait m_l_ptr_to_volatile( otype P | m_l_pointer( P ), @\use{m_l_pointer}@@\impl{m_l_ptr_to_volatile}@ otype T | ptr_to_volatile( P, T )) {@\use{ptr_to_volatile}@3738 trait m_l_ptr_to_volatile( otype P | m_l_pointer( P ),§\use{m_l_pointer}§§\impl{m_l_ptr_to_volatile}§ otype T | ptr_to_volatile( P, T )) {§\use{ptr_to_volatile}§ 3737 3739 P ?=?( P *, volatile T * ); 3738 3740 volatile T * ?=?( volatile T **, P ); 3739 3741 }; 3740 trait m_l_ptr_to_const_volatile( otype P | ptr_to_const_volatile( P ), @\use{ptr_to_const_volatile}@@\impl{m_l_ptr_to_const_volatile}@3741 otype T | m_l_ptr_to_volatile( P, T ) | m_l_ptr_to_const( P )) { @\use{m_l_ptr_to_const}@@\use{m_l_ptr_to_volatile}@3742 trait m_l_ptr_to_const_volatile( otype P | ptr_to_const_volatile( P ),§\use{ptr_to_const_volatile}§§\impl{m_l_ptr_to_const_volatile}§ 3743 otype T | m_l_ptr_to_volatile( P, T ) | m_l_ptr_to_const( P )) {§\use{m_l_ptr_to_const}§§\use{m_l_ptr_to_volatile}§ 3742 3744 P ?=?( P *, const volatile T * ); 3743 3745 const volatile T * ?=?( const volatile T **, P ); … … 3748 3750 An alternative specification can make use of the fact that qualification of the pointed-at type is part of a pointer type to capture that regularity. 3749 3751 \begin{lstlisting} 3750 trait m_l_ptr_like( type MyP | m_l_pointer( MyP ), @\use{m_l_pointer}@@\impl{m_l_ptr_like}@type CP | m_l_pointer( CP ) ) {3752 trait m_l_ptr_like( type MyP | m_l_pointer( MyP ),§\use{m_l_pointer}§§\impl{m_l_ptr_like}§ type CP | m_l_pointer( CP ) ) { 3751 3753 MyP ?=?( MyP *, CP ); 3752 3754 CP ?=?( CP *, MyP ); 3753 3755 }; 3754 3756 \end{lstlisting} 3755 The assertion ``\lstinline $| m_l_ptr_like( Safe_ptr, const int * )$'' should be read as3756 ``\lstinline $Safe_ptr$ is a pointer type like \lstinline$const int *$''.3757 The assertion ``\lstinline@| m_l_ptr_like( Safe_ptr, const int * )@'' should be read as 3758 ``\lstinline@Safe_ptr@ is a pointer type like \lstinline@const int *@''. 3757 3759 This specification has two defects, compared to the original four: there is no automatic assertion that dereferencing a 3758 \lstinline $MyP$ produces an lvalue of the type that \lstinline$CP$points at, and the3759 ``\lstinline $|m_l_pointer( CP )$'' assertion provides only a weak assurance that the argument passed to \lstinline$CP$really is a pointer type.3760 \lstinline@MyP@ produces an lvalue of the type that \lstinline@CP@ points at, and the 3761 ``\lstinline@|m_l_pointer( CP )@'' assertion provides only a weak assurance that the argument passed to \lstinline@CP@ really is a pointer type. 3760 3762 3761 3763 … … 3763 3765 3764 3766 Different operators often have related meanings; 3765 for instance, in C, ``\lstinline $+$'',3766 ``\lstinline $+=$'', and the two versions of ``\lstinline$++$'' perform variations of addition.3767 for instance, in C, ``\lstinline@+@'', 3768 ``\lstinline@+=@'', and the two versions of ``\lstinline@++@'' perform variations of addition. 3767 3769 Languages like {\CC} and Ada allow programmers to define operators for new types, but do not require that these relationships be preserved, or even that all of the operators be implemented. 3768 3770 Completeness and consistency is left to the good taste and discretion of the programmer. … … 3777 3779 The different comparison operators have obvious relationships, but there is no obvious subset of the operations to use in the implementation of the others. 3778 3780 However, it is usually convenient to implement a single comparison function that returns a negative integer, 0, or a positive integer if its first argument is respectively less than, equal to, or greater than its second argument; 3779 the library function \lstinline $strcmp$is an example.3780 3781 C and \CFA have an extra, non-obvious comparison operator: ``\lstinline $!$'', logical negation, returns 1 if its operand compares equal to 0, and 0 otherwise.3781 the library function \lstinline@strcmp@ is an example. 3782 3783 C and \CFA have an extra, non-obvious comparison operator: ``\lstinline@!@'', logical negation, returns 1 if its operand compares equal to 0, and 0 otherwise. 3782 3784 \begin{lstlisting} 3783 3785 trait comparable( otype T ) { … … 3828 3830 3829 3831 Note that, although an arithmetic type would certainly provide comparison functions, and an integral type would provide arithmetic operations, there does not have to be any relationship among 3830 \lstinline $int_base$, \lstinline$arith_base$ and \lstinline$comparable$.3832 \lstinline@int_base@, \lstinline@arith_base@ and \lstinline@comparable@. 3831 3833 Note also that these declarations provide guidance and assistance, but they do not define an absolutely minimal set of requirements. 3832 A truly minimal implementation of an arithmetic type might only provide 3833 \lstinline$0$, \lstinline$1$, and \lstinline$?-=?$, which would be used by polymorphic 3834 \lstinline$?+=?$, \lstinline$?*=?$, and \lstinline$?/=?$ functions. 3835 3836 Note also that \lstinline$short$ is an integer type in C11 terms, but has no operations! 3834 A truly minimal implementation of an arithmetic type might only provide \lstinline@0@, \lstinline@1@, and \lstinline@?-=?@, which would be used by polymorphic \lstinline@?+=?@, \lstinline@?*=?@, and \lstinline@?/=?@ functions. 3835 3836 Note also that \lstinline@short@ is an integer type in C11 terms, but has no operations! 3837 3837 3838 3838 … … 3841 3841 3842 3842 Restrict allowed to qualify anything, or type/dtype parameters, but only affects pointers. 3843 This gets into \lstinline $noalias$territory.3844 Qualifying anything (``\lstinline $short restrict rs$'') means pointer parameters of \lstinline$?++$, etc, would need restrict qualifiers.3843 This gets into \lstinline@noalias@ territory. 3844 Qualifying anything (``\lstinline@short restrict rs@'') means pointer parameters of \lstinline@?++@, etc, would need restrict qualifiers. 3845 3845 3846 3846 Enumerated types. … … 3852 3852 Color, enum Color ) really make sense? ?++ does, but it adds (int)1. 3853 3853 3854 Operators on {,signed,unsigned} char and other small types. ?<?harmless;3854 Operators on {,signed,unsigned} char and other small types. \lstinline@?<?@ harmless; 3855 3855 ?*? questionable for chars. 3856 3856 Generic selections make these choices visible. … … 3858 3858 ``promotion'' function? 3859 3859 3860 \lstinline $register$assignment might be handled as assignment to a temporary with copying back and forth, but copying must not be done by assignment.3861 3862 Don't use ptrdiff\_tby name in the predefineds.3860 \lstinline@register@ assignment might be handled as assignment to a temporary with copying back and forth, but copying must not be done by assignment. 3861 3862 Don't use \lstinline@ptrdiff_t@ by name in the predefineds. 3863 3863 3864 3864 Polymorphic objects.
Note: See TracChangeset
for help on using the changeset viewer.