Changes in / [830c21a:353d168]
- Files:
-
- 3 added
- 5 deleted
- 2 edited
-
doc/TeX/cfa.sty (added)
-
doc/man/README (added)
-
doc/man/cfa.1 (added)
-
doc/refrat/Makefile (deleted)
-
doc/refrat/indexstyle (deleted)
-
doc/refrat/predefined.sed (deleted)
-
doc/refrat/refrat.bib (deleted)
-
doc/refrat/refrat.tex (modified) (1 diff)
-
doc/refrat/xref.tex (deleted)
-
src/CodeGen/CodeGenerator.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/refrat/refrat.tex
r830c21a r353d168 1 \documentclass[openright,twoside]{report}2 \usepackage{fullpage,times}3 \usepackage{xspace}4 \usepackage{varioref}5 \usepackage{listings}6 \usepackage{latexsym} % \Box7 \usepackage{mathptmx} % better math font with "times"8 \usepackage[pagewise]{lineno}9 \renewcommand{\linenumberfont}{\scriptsize\sffamily}10 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref}11 \usepackage{breakurl}12 \urlstyle{sf}13 14 %\input code.sty15 \input xref.tex16 17 \newcommand{\define}[1]{\emph{#1\/}\index{#1}}18 \newenvironment{rationale}{%19 \begin{quotation}\noindent$\Box$\enspace20 }{%21 \hfill\enspace$\Box$\end{quotation}22 }%23 \newcommand{\rewrite}{\(\Rightarrow\)}24 \newcommand{\rewriterules}{\paragraph{Rewrite Rules}\hskip1em\par\noindent}25 \newcommand{\examples}{\paragraph{Examples}\hskip1em\par\noindent}26 \newcommand{\semantics}{\paragraph{Semantics}\hskip1em\par\noindent}27 \newcommand{\constraints}{\paragraph{Constraints}\hskip1em\par\noindent}28 \newenvironment{predefined}{%29 \paragraph{Predefined Identifiers}%30 % \begin{code}%31 }{%32 % \end{code}33 }%34 35 \def\syntax{\paragraph{Syntax}\trivlist\parindent=.5in\item[\hskip.5in]}36 \let\endsyntax=\endtrivlist37 \newcommand{\lhs}[1]{\par{\it #1:}\index{#1@{\it #1}|italic}}38 \newcommand{\rhs}{\hfil\break\hbox{\hskip1in}}39 \newcommand{\oldlhs}[1]{{\it #1: \ldots}\index{#1@{\it #1}|italic}}40 \newcommand{\nonterm}[1]{{\it #1\/}\index{#1@{\it #1}|italic}}41 \newcommand{\opt}{$_{opt}$\ }42 43 \renewcommand{\reftextfaceafter}{\unskip}44 \renewcommand{\reftextfacebefore}{\unskip}45 \renewcommand{\reftextafter}{\unskip}46 \renewcommand{\reftextbefore}{\unskip}47 \renewcommand{\reftextfaraway}[1]{\unskip, p.~\pageref{#1}}48 \renewcommand{\reftextpagerange}[2]{\unskip, pp.~\pageref{#1}--\pageref{#2}}49 \newcommand{\VRef}[2][Section]{\ifx#1\@empty\else{#1}\nobreakspace\fi\vref{#2}}50 \newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}}51 52 \newcommand{\CFA}{Cforall\xspace}53 \newcommand{\CFAA}{C$\forall$\xspace}54 \newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace}55 \def\c11{ISO/IEC C}% cannot have numbers in latex command name56 57 \lstdefinelanguage{CFA}[ANSI]{C}%58 {morekeywords={asm,_Atomic,catch,choose,_Complex,context,dtype,fallthru,forall,ftype,_Imaginary,lvalue,restrict,throw,try,type,},59 }60 61 \lstset{62 language=CFA,63 columns=fullflexible,64 basicstyle=\sf\small,65 tabsize=4,66 xleftmargin=\parindent,67 escapechar=@,68 %showtabs=true,69 %tab=\rightarrowfill,70 }71 72 \setcounter{secnumdepth}{3} % number subsubsections73 \makeindex74 75 \begin{document}76 \pagestyle{headings}77 \linenumbers % comment out to turn off line numbering78 79 \title{\CFA (\CFAA) Reference Manual and Rationale}80 \author{Glen Ditchfield}81 \date{DRAFT\\\today}82 83 \pagenumbering{roman}84 \pagestyle{plain}85 86 \maketitle87 88 \vspace*{\fill}89 \thispagestyle{empty}90 \noindent91 \copyright\,2015 Glen Ditchfield \\ \\92 \noindent93 This work is licensed under the Creative Commons Attribution 4.0 International License. To view a94 copy of this license, visit {\small\url{http://creativecommons.org/licenses/by/4.0}}.95 \vspace*{1in}96 97 \clearpage98 \pdfbookmark[1]{Contents}{section}99 \tableofcontents100 101 \clearpage102 \pagenumbering{arabic}103 104 105 \chapter*{Introduction}\addcontentsline{toc}{chapter}{Introduction}106 107 This document is a reference manual and rationale for \CFA, a polymorphic extension of the C108 programming language. It makes frequent reference to the {\c11} standard \cite{ANS:C11}, and109 occasionally compares \CFA to {\CC} \cite{c++}.110 111 The manual deliberately imitates the ordering of the {\c11} standard (although the section numbering112 differs). Unfortunately, this means that the manual contains more ``forward references'' than113 usual, and that it will be hard to follow if the reader does not have a copy of the {\c11} standard114 near-by. For a gentle introduction to \CFA, see the companion document ``An Overview of115 \CFA'' \cite{Ditchfield96:Overview}.116 117 \begin{rationale}118 Commentary (like this) is quoted with quads. Commentary usually deals with subtle points, the119 rationale behind a rule, and design decisions.120 \end{rationale}121 122 % No ``Scope'' or ``Normative references'' chapters yet.123 \setcounter{chapter}{2}124 \chapter{Terms, definitions, and symbols}125 Terms from the {\c11} standard used in this document have the same meaning as in the {\c11}126 standard.127 128 % No ``Conformance'' or ``Environment'' chapters yet.129 \setcounter{chapter}{5}130 \chapter{Language}131 \section{Notation}132 The syntax notation used in this document is the same as is used in the {\c11} standard, with one133 exception: ellipsis in the definition of a nonterminal, as in ``\emph{declaration:} \ldots'',134 indicates that these rules extend a previous definition, which occurs in this document or in the135 {\c11} standard.136 137 138 \section{Concepts}139 140 141 \subsection{Scopes of identifiers}\index{scopes}142 143 \CFA's scope rules differ from C's in one major respect: a declaration of an identifier may144 overload\index{overloading} outer declarations of lexically identical identifiers in the same name145 space\index{name spaces}, instead of hiding them. The outer declaration is hidden if the two146 declarations have compatible type\index{compatible type}, or if one declares an array type and the147 other declares a pointer type and the element type and pointed-at type are compatible, or if one has148 function type and the other is a pointer to a compatible function type, or if one declaration is a149 \lstinline$type$\use{type} or \lstinline$typedef$\use{typedef} declaration and the other is not.150 The outer declaration becomes visible\index{visible} when the scope of the inner declaration151 terminates.152 \begin{rationale}153 Hence, a \CFA program can declare an \lstinline$int v$ and a \lstinline$float v$ in the same154 scope; a {\CC} program can not.155 \end{rationale}156 157 158 \subsection{Linkage of identifiers}\index{linkage}159 160 \CFA's linkage rules differ from C's in only one respect: instances of a particular identifier161 with external or internal linkage do not necessarily denote the same object or function. Instead,162 in the set of translation units and libraries that constitutes an entire program, any two instances163 of a particular identifier with external linkage\index{external linkage} denote the same object or164 function if they have compatible types\index{compatible type}, or if one declares an array type and165 the other declares a pointer type and the element type and pointed-at type are compatible, or if one166 has function type and the other is a pointer to a compatible function type. Within one translation167 unit, each instance of an identifier with internal linkage\index{internal linkage} denotes the same168 object or function in the same circumstances. Identifiers with no linkage\index{no linkage} always169 denote unique entities.170 \begin{rationale}171 A \CFA program can declare an \lstinline$extern int v$ and an \lstinline$extern float v$; a C172 program cannot.173 \end{rationale}174 175 \section{Conversions}176 \CFA defines situations where values of one type are automatically converted to another type.177 These conversions are called \define{implicit conversions}. The programmer can request178 \define{explicit conversions} using cast expressions.179 180 181 \subsection{Arithmetic operands}182 \setcounter{subsubsection}{7}183 184 185 \subsubsection{Safe arithmetic conversions}186 In C, a pattern of conversions known as the \define{usual arithmetic conversions} is used with most187 binary arithmetic operators to convert the operands to a common type and determine the type of the188 operator's result. In \CFA, these conversions play a role in overload resolution, and189 collectively are called the \define{safe arithmetic conversions}.190 191 Let \(int_r\) and \(unsigned_r\) be the signed and unsigned integer types with integer conversion192 rank\index{integer conversion rank} \index{rank|see{integer conversion rank}} $r$. Let193 \(unsigned_{mr}\) be the unsigned integer type with maximal rank.194 195 The following conversions are \emph{direct} safe arithmetic conversions.196 \begin{itemize}197 \item198 The integer promotions\index{integer promotions}.199 200 \item201 For every rank $r$ greater than or equal to the rank of \lstinline$int$, conversion from \(int_r\)202 to \(unsigned_r\).203 204 \item205 For every rank $r$ greater than or equal to the rank of \lstinline$int$, where \(int_{r+1}\) exists206 and can represent all values of \(unsigned_r\), conversion from \(unsigned_r\) to \(int_{r+1}\).207 208 \item209 Conversion from \(unsigned_{mr}\) to \lstinline$float$.210 211 \item212 Conversion from an enumerated type to its compatible integer type.213 214 \item215 Conversion from \lstinline$float$ to \lstinline$double$, and from \lstinline$double$ to216 \lstinline$long double$.217 218 \item219 Conversion from \lstinline$float _Complex$ to \lstinline$double _Complex$,220 and from \lstinline$double _Complex$ to \lstinline$long double _Complex$.221 222 \begin{sloppypar}223 \item224 Conversion from \lstinline$float _Imaginary$ to \lstinline$double _Imaginary$, and from225 \lstinline$double _Imaginary$ to \lstinline$long double$ \lstinline$_Imaginary$, if the226 implementation supports imaginary types.227 \end{sloppypar}228 \end{itemize}229 230 If type \lstinline$T$ can be converted to type \lstinline$U$ by a safe direct arithmetic conversion231 and type \lstinline$U$ can be converted to type \lstinline$V$ by a safe arithmetic conversion, then232 the conversion from \lstinline$T$ to type \lstinline$V$ is an \emph{indirect} safe arithmetic233 conversion.234 235 \begin{rationale}236 Note that {\c11} does not include conversion from real types\index{real type} to complex237 types\index{complex type} in the usual arithmetic conversions, and \CFA does not include them as238 safe conversions.239 \end{rationale}240 241 242 \subsection{Other operands}243 \setcounter{subsubsection}{3}244 245 246 \subsubsection{Anonymous structures and unions}247 \label{anon-conv}248 249 If an expression's type is a pointer to a structure or union type that has a member that is an250 anonymous structure\index{anonymous structure} or an anonymous union\index{anonymous union}, it can251 be implicitly converted\index{implicit conversions} to a pointer to the anonymous structure's or252 anonymous union's type. The result of the conversion is a pointer to the member.253 254 \examples255 \begin{lstlisting}256 struct point {257 int x, y;258 };259 void move_by(struct point * p1, struct point * p2) {@\impl{move_by}@260 p1->x += p2.x;261 p1->y += p2.y;262 }263 264 struct color_point {265 enum { RED, BLUE, GREEN } color;266 struct point;267 } cp1, cp2;268 move_to(&cp1, &cp2);269 \end{lstlisting}270 Thanks to implicit conversion, the two arguments that \lstinline$move_by()$ receives are pointers to271 \lstinline$cp1$'s second member and \lstinline$cp2$'s second member.272 273 274 \subsubsection{Specialization}275 A function or value whose type is polymorphic may be implicitly converted to one whose type is less276 polymorphic\index{less polymorphic} by binding values to one or more of its inferred277 parameters\index{inferred parameter}. Any value that is legal for the inferred parameter may be278 used, including other inferred parameters.279 280 If, after the inferred parameter binding, an assertion parameter\index{assertion parameters} has no281 inferred parameters in its type, then an object or function must be visible at the point of the282 specialization that has the same identifier as the assertion parameter and has a type that is283 compatible\index{compatible type} with or can be specialized to the type of the assertion parameter.284 The assertion parameter is bound to that object or function.285 286 The type of the specialization is the type of the original with the bound inferred parameters and287 the bound assertion parameters replaced by their bound values.288 289 \examples290 The type291 \begin{lstlisting}292 forall( type T, type U ) void (*)( T, U );293 \end{lstlisting}294 can be specialized to (among other things)295 \begin{lstlisting}296 forall( type T ) void (*)( T, T ); // U bound to T297 forall( type T ) void (*)( T, real ); // U bound to real298 forall( type U ) void (*)( real, U ); // T bound to real299 void f( real, real ); // both bound to real300 \end{lstlisting}301 302 The type303 \begin{lstlisting}304 forall( type T | T ?+?( T, T )) T (*)( T );305 \end{lstlisting}306 can be specialized to (among other things)307 \begin{lstlisting}308 int (*)( int ); // T bound to int, and T ?+?(T, T ) bound to int ?+?( int, int )309 \end{lstlisting}310 311 312 \subsubsection{Safe conversions}313 314 A \define{direct safe conversion} is one of the following conversions:315 \begin{itemize}316 \item317 a direct safe arithmetic conversion;318 \item319 from any object type or incomplete type to \lstinline$void$;320 \item321 from a pointer to any non-\lstinline$void$ type to a pointer to \lstinline$void$;322 \item323 from a pointer to any type to a pointer to a more qualified version of the type\index{qualified324 type};325 \item326 from a pointer to a structure or union type to a pointer to the type of a member of the structure or327 union that is an anonymous structure\index{anonymous structure} or an anonymous328 union\index{anonymous union};329 \item330 within the scope of an initialized type declaration\index{type declaration}, conversions between a331 type and its implementation or between a pointer to a type and a pointer to its implementation.332 \end{itemize}333 334 Conversions that are not safe conversions are \define{unsafe conversions}.335 \begin{rationale}336 As in C, there is an implicit conversion from \lstinline$void *$ to any pointer type. This is337 clearly dangerous, and {\CC} does not have this implicit conversion.338 \CFA\index{deficiencies!void * conversion} keeps it, in the interest of remaining as pure a339 superset of C as possible, but discourages it by making it unsafe.340 \end{rationale}341 342 343 \subsection{Conversion cost}344 345 The \define{conversion cost} of a safe\index{safe conversions}346 conversion\footnote{Unsafe\index{unsafe conversions} conversions do not have defined conversion347 costs.} is a measure of how desirable or undesirable it is. It is defined as follows.348 \begin{itemize}349 \item350 The cost of a conversion from any type to itself is 0.351 352 \item353 The cost of a direct safe conversion is 1.354 355 \item356 The cost of an indirect safe arithmetic conversion is the smallest number of direct conversions357 needed to make up the conversion.358 \end{itemize}359 360 \examples361 In the following, assume an implementation that does not provide any extended integer types.362 363 \begin{itemize}364 \item365 The cost of an implicit conversion from \lstinline$int$ to \lstinline$long$ is 1. The cost of an366 implicit conversion from \lstinline$long$ to \lstinline$double$ is 3, because it is defined in terms367 of conversions from \lstinline$long$ to \lstinline$unsigned long$, then to \lstinline$float$, and368 then to \lstinline$double$.369 370 \item371 If \lstinline$int$ can represent all the values of \lstinline$unsigned short$, then the cost of an372 implicit conversion from \lstinline$unsigned short$ to \lstinline$unsigned$ is 2:373 \lstinline$unsigned short$ to \lstinline$int$ to \lstinline$unsigned$. Otherwise,374 \lstinline$unsigned short$ is converted directly to \lstinline$unsigned$, and the cost is 1.375 376 \item377 If \lstinline$long$ can represent all the values of \lstinline$unsigned$, then the conversion cost378 of \lstinline$unsigned$ to \lstinline$long$ is 1. Otherwise, the conversion is an unsafe379 conversion, and its conversion cost is undefined.380 \end{itemize}381 382 \section{Lexical elements}383 \subsection{Keywords}384 \begin{syntax}385 \oldlhs{keyword}386 \rhs \lstinline$forall$387 \rhs \lstinline$lvalue$388 \rhs \lstinline$context$389 \rhs \lstinline$dtype$390 \rhs \lstinline$ftype$391 \rhs \lstinline$type$392 \end{syntax}393 394 395 \subsection{Identifiers}396 397 \CFA allows operator overloading\index{overloading} by associating operators with special398 function identifiers. Furthermore, the constants ``\lstinline$0$'' and ``\lstinline$1$'' have399 special status for many of C's data types (and for many programmer-defined data types as well), so400 \CFA treats them as overloadable identifiers. Programmers can use these identifiers to declare401 functions and objects that implement operators and constants for their own types.402 403 404 \setcounter{subsubsection}{2}405 \subsubsection{Constant identifiers}406 407 \begin{syntax}408 \oldlhs{identifier}409 \rhs \lstinline$0$410 \rhs \lstinline$1$411 \end{syntax}412 413 \index{constant identifiers}\index{identifiers!for constants} The tokens ``\lstinline$0$''\impl{0}414 and ``\lstinline$1$''\impl{1} are identifiers. No other tokens defined by the rules for integer415 constants are considered to be identifiers.416 \begin{rationale}417 Why ``\lstinline$0$'' and ``\lstinline$1$''? Those integers have special status in C. All scalar418 types can be incremented and decremented, which is defined in terms of adding or subtracting 1. The419 operations ``\lstinline$&&$'', ``\lstinline$||$'', and ``\lstinline$!$'' can be applied to any420 scalar arguments, and are defined in terms of comparison against 0. A \nonterm{constant-expression}421 that evaluates to 0 is effectively compatible with every pointer type.422 423 In C, the integer constants 0 and 1 suffice because the integer promotion rules can convert them to424 any arithmetic type, and the rules for pointer expressions treat constant expressions evaluating to425 0 as a special case. However, user-defined arithmetic types often need the equivalent of a 1 or 0426 for their functions or operators, polymorphic functions often need 0 and 1 constants of a type427 matching their polymorphic parameters, and user-defined pointer-like types may need a null value.428 Defining special constants for a user-defined type is more efficient than defining a conversion to429 the type from \lstinline$_Bool$.430 431 Why \emph{just} ``\lstinline$0$'' and ``\lstinline$1$''? Why not other integers? No other integers432 have special status in C. A facility that let programmers declare specific433 constants---``\lstinline$const Rational 12$'', for instance---would not be much of an improvement.434 Some facility for defining the creation of values of programmer-defined types from arbitrary integer435 tokens would be needed. The complexity of such a feature doesn't seem worth the gain.436 \end{rationale}437 438 439 \subsubsection{Operator identifiers}440 441 \index{operator identifiers}\index{identifiers!for operators} Table \ref{opids} lists the442 programmer-definable operator identifiers and the operations they are associated with. Functions443 that are declared with (or pointed at by function pointers that are declared with) these identifiers444 can be called by expressions that use the operator tokens and syntax, or the operator identifiers445 and ``function call'' syntax. The relationships between operators and function calls are discussed446 in descriptions of the operators.447 448 \begin{table}[hbt]449 \hfil450 \begin{tabular}[t]{ll}451 %identifier & operation \\ \hline452 \lstinline$?[?]$ & subscripting \impl{?[?]}\\453 \lstinline$?()$ & function call \impl{?()}\\454 \lstinline$?++$ & postfix increment \impl{?++}\\455 \lstinline$?--$ & postfix decrement \impl{?--}\\456 \lstinline$++?$ & prefix increment \impl{++?}\\457 \lstinline$--?$ & prefix decrement \impl{--?}\\458 \lstinline$*?$ & dereference \impl{*?}\\459 \lstinline$+?$ & unary plus \impl{+?}\\460 \lstinline$-?$ & arithmetic negation \impl{-?}\\461 \lstinline$~?$ & bitwise negation \impl{~?}\\462 \lstinline$!?$ & logical complement \impl{"!?}\\463 \lstinline$?*?$ & multiplication \impl{?*?}\\464 \lstinline$?/?$ & division \impl{?/?}\\465 \end{tabular}\hfil466 \begin{tabular}[t]{ll}467 %identifier & operation \\ \hline468 \lstinline$?%?$ & remainder \impl{?%?}\\469 \lstinline$?+?$ & addition \impl{?+?}\\470 \lstinline$?-?$ & subtraction \impl{?-?}\\471 \lstinline$?<<?$ & left shift \impl{?<<?}\\472 \lstinline$?>>?$ & right shift \impl{?>>?}\\473 \lstinline$?<?$ & less than \impl{?<?}\\474 \lstinline$?<=?$ & less than or equal \impl{?<=?}\\475 \lstinline$?>=?$ & greater than or equal \impl{?>=?}\\476 \lstinline$?>?$ & greater than \impl{?>?}\\477 \lstinline$?==?$ & equality \impl{?==?}\\478 \lstinline$?!=?$ & inequality \impl{?"!=?}\\479 \lstinline$?&?$ & bitwise AND \impl{?&?}\\480 \end{tabular}\hfil481 \begin{tabular}[t]{ll}482 %identifier & operation \\ \hline483 \lstinline$?^?$ & exclusive OR \impl{?^?}\\484 \lstinline$?|?$ & inclusive OR \impl{?"|?}\\485 \lstinline$?=?$ & simple assignment \impl{?=?}\\486 \lstinline$?*=?$ & multiplication assignment \impl{?*=?}\\487 \lstinline$?/=?$ & division assignment \impl{?/=?}\\488 \lstinline$?%=?$ & remainder assignment \impl{?%=?}\\489 \lstinline$?+=?$ & addition assignment \impl{?+=?}\\490 \lstinline$?-=?$ & subtraction assignment \impl{?-=?}\\491 \lstinline$?<<=?$ & left-shift assignment \impl{?<<=?}\\492 \lstinline$?>>=?$ & right-shift assignment \impl{?>>=?}\\493 \lstinline$?&=?$ & bitwise AND assignment \impl{?&=?}\\494 \lstinline$?^=?$ & exclusive OR assignment \impl{?^=?}\\495 \lstinline$?|=?$ & inclusive OR assignment \impl{?"|=?}\\496 \end{tabular}497 \hfil498 \caption{Operator Identifiers}499 \label{opids}500 \end{table}501 502 \begin{rationale}503 Operator identifiers are made up of the characters of the operator token, with question marks added504 to mark the positions of the arguments of operators. The question marks serve as mnemonic devices;505 programmers can not create new operators by arbitrarily mixing question marks and other506 non-alphabetic characters. Note that prefix and postfix versions of the increment and decrement507 operators are distinguished by the position of the question mark.508 \end{rationale}509 510 \begin{rationale}511 The use of ``\lstinline$?$'' in identifiers means that some C programs are not \CFA programs.512 For instance, the sequence of characters ``\lstinline$(i < 0)?--i:i$'' is legal in a C program, but513 a \CFA compiler will detect a syntax error because it will treat ``\lstinline$?--$'' as an514 identifier, not as the two tokens ``\lstinline$?$'' and ``\lstinline$--$''.515 \end{rationale}516 517 \begin{rationale}518 Certain operators \emph{cannot} be defined by the programmer:519 \begin{itemize}520 \item521 The logical operators ``\lstinline$&&$'' and ``\lstinline$||$'', and the conditional operator522 ``\lstinline$?:$''. These operators do not always evaluate their operands, and hence can not be523 properly defined by functions unless some mechanism like call-by-name is added to the language.524 Note that the definitions of ``\lstinline$&&$'' and ``\lstinline$||$'' say that they work by525 checking that their arguments are unequal to 0, so defining ``\lstinline$!=$'' and ``\lstinline$0$''526 for user-defined types is enough to allow them to be used in logical expressions.527 528 \item529 The comma operator\index{comma expression}. It is a control-flow operator like those above.530 Changing its meaning seems pointless and confusing.531 532 \item533 The ``address of'' operator. It would seem useful to define a unary ``\lstinline$&$'' operator that534 returns values of some programmer-defined pointer-like type. The problem lies with the type of the535 operator. Consider the expression ``\lstinline$p = &x$'', where \lstinline$x$ is of type536 \lstinline$T$ and \lstinline$p$ has the programmer-defined type \lstinline$T_ptr$. The expression537 might be treated as a call to the unary function ``\lstinline$&?$''. Now what is the type of the538 function's parameter? It can not be \lstinline$T$, because then \lstinline$x$ would be passed by539 value, and there is no way to create a useful pointer-like result from a value. Hence the parameter540 must have type \lstinline$T *$. But then the expression must be rewritten as ``\lstinline$p = &?( &x )$''541 ---which doesn't seem like progress!542 543 The rule for address-of expressions would have to be something like ``keep applying address-of544 functions until you get one that takes a pointer argument, then use the built-in operator and545 stop''. It seems simpler to define a conversion function from \lstinline$T *$ to \lstinline$T_ptr$.546 547 \item548 The \lstinline$sizeof$ operator. It is already defined for every object type, and intimately tied549 into the language's storage allocation model. Redefining it seems pointless.550 551 \item552 The ``member of'' operators ``\lstinline$.$'' and ``\lstinline$->$''. These are not really infix553 operators, since their right ``operand'' is not a value or object.554 555 \item556 Cast operators\index{cast expression}. Anything that can be done with an explicit cast can be done557 with a function call. The difference in syntax is small.558 \end{itemize}559 \end{rationale}560 561 562 \section{Expressions}563 \CFA allows operators and identifiers to be overloaded. Hence, each expression can have a number564 of \define{interpretations}, each of which has a different type. The interpretations that are565 potentially executable are called \define{valid interpretations}. The set of interpretations566 depends on the kind of expression and on the interpretations of the subexpressions that it contains.567 The rules for determining the valid interpretations of an expression are discussed below for each568 kind of expression. Eventually the context of the outermost expression chooses one interpretation569 of that expression.570 571 An \define{ambiguous interpretation} is an interpretation which does not specify the exact object or572 function denoted by every identifier in the expression. An expression can have some interpretations573 that are ambiguous and others that are unambiguous. An expression that is chosen to be executed574 shall not be ambiguous.575 576 The \define{best valid interpretations} are the valid interpretations that use the fewest577 unsafe\index{unsafe conversions} conversions. Of these, the best are those where the functions and578 objects involved are the least polymorphic\index{less polymorphic}. Of these, the best have the579 lowest total conversion cost\index{conversion cost}, including all implicit conversions in the580 argument expressions. Of these, the best have the highest total conversion cost for the implicit581 conversions (if any) applied to the argument expressions. If there is no single best valid582 interpretation, or if the best valid interpretation is ambiguous, then the resulting interpretation583 is ambiguous\index{ambiguous interpretation}.584 585 \begin{rationale}586 \CFA's rules for selecting the best interpretation are designed to allow overload resolution to587 mimic C's operator semantics. In C, the ``usual arithmetic conversions'' are applied to the588 operands of binary operators if necessary to convert the operands to types with a common real type.589 In \CFA, those conversions are ``safe''. The ``fewest unsafe conversions'' rule ensures that the590 usual conversions are done, if possible. The ``lowest total expression cost'' rule chooses the591 proper common type. The odd-looking ``highest argument conversion cost'' rule ensures that, when592 unary expressions must be converted, conversions of function results are preferred to conversion of593 function arguments: \lstinline$(double)-i$ will be preferred to \lstinline$-(double)i$.594 595 The ``least polymorphic'' rule reduces the number of polymorphic function calls, since such596 functions are presumably more expensive than monomorphic functions and since the more specific597 function is presumably more appropriate. It also gives preference to monomorphic values (such as598 the \lstinline$int$ \lstinline$0$) over polymorphic values (such as the null pointer599 \lstinline$0$)\use{0}\index{null pointer}. However, interpretations that call polymorphic functions600 are preferred to interpretations that perform unsafe conversions, because those conversions601 potentially lose accuracy or violate strong typing.602 603 There are two notable differences between \CFA's overload resolution rules and the rules for604 {\CC} defined in \cite{c++}. First, the result type of a function plays a role. In {\CC}, a605 function call must be completely resolved based on the arguments to the call in most circumstances.606 In \CFA, a function call may have several interpretations, each with a different result type, and607 the interpretations of the containing context choose among them. Second, safe conversions are used608 to choose among interpretations of all sorts of functions; in {\CC}, the ``usual arithmetic609 conversions'' are a separate set of rules that apply only to the built-in operators.610 \end{rationale}611 612 Expressions involving certain operators\index{operator identifiers} are considered to be equivalent613 to function calls. A transformation from ``operator'' syntax to ``function call'' syntax is defined614 by \define{rewrite rules}. Each operator has a set of predefined functions that overload its615 identifier. Overload resolution determines which member of the set is executed in a given616 expression. The functions have internal linkage\index{internal linkage} and are implicitly declared617 with file scope\index{file scope}. The predefined functions and rewrite rules are discussed below618 for each of these operators.619 \begin{rationale}620 Predefined functions and constants have internal linkage because that simplifies optimization in621 traditional compile-and-link environments. For instance, ``\lstinline$an_int + an_int$'' is622 equivalent to ``\lstinline$?+?(an_int, an_int)$''. If integer addition has not been redefined in623 the current scope, a compiler can generate code to perform the addition directly. If predefined624 functions had external linkage, this optimization would be difficult.625 \end{rationale}626 627 \begin{rationale}628 Since each subsection describes the interpretations of an expression in terms of the interpretations629 of its subexpressions, this chapter can be taken as describing an overload resolution algorithm that630 uses one bottom-up pass over an expression tree. Such an algorithm was first described (for Ada) by631 Baker \cite{Bak:overload}. It is extended here to handle polymorphic functions and arithmetic632 conversions. The overload resolution rules and the predefined functions have been chosen so that,633 in programs that do not introduce overloaded declarations, expressions will have the same meaning in634 C and in \CFA.635 \end{rationale}636 637 \begin{rationale}638 Expression syntax is quoted from the {\c11} standard. The syntax itself defines the precedence and639 associativity of operators. The sections are arranged in decreasing order of precedence, with all640 operators in a section having the same precedence.641 \end{rationale}642 643 \subsection{Primary expressions}644 \begin{syntax}645 \lhs{primary-expression}646 \rhs \nonterm{identifier}647 \rhs \nonterm{constant}648 \rhs \nonterm{string-literal}649 \rhs \lstinline$($ \nonterm{expression} \lstinline$)$650 \rhs \nonterm{generic-selection}651 \end{syntax}652 653 \paragraph{Predefined Identifiers}%654 \begin{lstlisting}655 const int 1;@\use{1}@656 const int 0;@\use{0}@657 forall( dtype DT ) DT *const 0;658 forall( ftype FT ) FT *const 0;659 \end{lstlisting}660 661 \semantics662 The valid interpretations\index{valid interpretations} of an \nonterm{identifier} are given by the663 visible\index{visible} declarations of the identifier.664 665 A \nonterm{constant} or \nonterm{string-literal} has one valid interpretation, which has the type666 and value defined by {\c11}. The predefined integer identifiers ``\lstinline$1$'' and667 ``\lstinline$0$'' have the integer values 1 and 0, respectively. The other two predefined668 ``\lstinline$0$'' identifiers are bound to polymorphic pointer values that, when669 specialized\index{specialization} with a data type or function type respectively, produce a null670 pointer of that type.671 672 A parenthesised expression has the same interpretations as the contained \nonterm{expression}.673 674 \examples675 The expression \lstinline$(void *)0}$\use{0} specializes the (polymorphic) null pointer to a null676 pointer to \lstinline$void$. \lstinline$(const void *)0$ does the same, and also uses a safe677 conversion from \lstinline$void *$ to \lstinline$const void *$. In each case, the null pointer678 conversion is better\index{best valid interpretations} than the unsafe conversion of the integer679 \lstinline$0$ to a pointer.680 681 \begin{rationale}682 Note that the predefined identifiers have addresses.683 684 \CFA does not have C's concept of ``null pointer constants'', which are not typed values but685 special strings of tokens. The C token ``\lstinline$0$'' is an expression of type \lstinline$int$686 with the value ``zero'', and it \emph{also} is a null pointer constant. Similarly,687 ``\lstinline$(void *)0$ is an expression of type \lstinline$(void *)$ whose value is a null pointer,688 and it also is a null pointer constant. However, in C, ``\lstinline$(void *)(void *)0$'' is689 \emph{not} a null pointer constant, even though it is null-valued, a pointer, and constant! The690 semantics of C expressions contain many special cases to deal with subexpressions that are null691 pointer constants.692 693 \CFA handles these cases through overload resolution. The declaration694 \begin{lstlisting}695 forall( dtype DT ) DT *const 0;696 \end{lstlisting}697 means that \lstinline$0$ is a polymorphic object, and contains a value that can have \emph{any}698 pointer-to-object type or pointer-to-incomplete type. The only such value is the null pointer.699 Therefore the type \emph{alone} is enough to identify a null pointer. Where C defines an operator700 with a special case for the null pointer constant, \CFA defines predefined functions with a701 polymorphic object parameter.702 \end{rationale}703 704 \subsubsection{Generic selection}705 \constraints The best interpretation of the controlling expression shall be706 unambiguous\index{ambiguous interpretation}, and shall have type compatible with at most one of the707 types named in its generic association list. If a generic selection has no \lstinline$default$708 generic association, the best interpretation of its controlling expression shall have type709 compatible with exactly one of the types named in its generic association list.710 711 \semantics712 A generic selection has the same interpretations as its result expression.713 714 715 \subsection{Postfix operators}716 717 \begin{syntax}718 \lhs{postfix-expression}719 \rhs \nonterm{primary-expression}720 \rhs \nonterm{postfix-expression} \lstinline$[$ \nonterm{expression} \lstinline$]$721 \rhs \nonterm{postfix-expression} \lstinline$($722 \nonterm{argument-expression-list}\opt \lstinline$)$723 \rhs \nonterm{postfix-expression} \lstinline$.$ \nonterm{identifier}724 \rhs \nonterm{postfix-expression} \lstinline$->$ \nonterm{identifier}725 \rhs \nonterm{postfix-expression} \lstinline$++$726 \rhs \nonterm{postfix-expression} \lstinline$--$727 \rhs \lstinline$($ \nonterm{type-name} \lstinline$)$ \lstinline${$ \nonterm{initializer-list} \lstinline$}$728 \rhs \lstinline$($ \nonterm{type-name} \lstinline$)$ \lstinline${$ \nonterm{initializer-list} \lstinline$,$ \lstinline$}$729 \lhs{argument-expression-list}730 \rhs \nonterm{assignment-expression}731 \rhs \nonterm{argument-expression-list} \lstinline$,$732 \nonterm{assignment-expression}733 \end{syntax}734 735 \rewriterules736 \begin{lstlisting}737 a[b] @\rewrite@ ?[?]( b, a ) // if a has integer type */@\use{?[?]}@738 a[b] @\rewrite@ ?[?]( a, b ) // otherwise739 a( ${\em arguments }$ ) @\rewrite@ ?()( a, ${\em arguments} )$@\use{?()}@740 a++ @\rewrite@ ?++(&( a ))@\use{?++}@741 a-- @\rewrite@ ?--(&( a ))@\use{?--}@742 \end{lstlisting}743 744 \subsubsection{Array subscripting}745 \begin{lstlisting}746 forall( type T ) lvalue T ?[?]( T *, ptrdiff_t );@\use{ptrdiff_t}@747 forall( type T ) lvalue _Atomic T ?[?]( _Atomic T *, ptrdiff_t );748 forall( type T ) lvalue const T ?[?]( const T *, ptrdiff_t );749 forall( type T ) lvalue restrict T ?[?]( restrict T *, ptrdiff_t );750 forall( type T ) lvalue volatile T ?[?]( volatile T *, ptrdiff_t );751 forall( type T ) lvalue _Atomic const T ?[?]( _Atomic const T *, ptrdiff_t );752 forall( type T ) lvalue _Atomic restrict T ?[?]( _Atomic restrict T *, ptrdiff_t );753 forall( type T ) lvalue _Atomic volatile T ?[?]( _Atomic volatile T *, ptrdiff_t );754 forall( type T ) lvalue const restrict T ?[?]( const restrict T *, ptrdiff_t );755 forall( type T ) lvalue const volatile T ?[?]( const volatile T *, ptrdiff_t );756 forall( type T ) lvalue restrict volatile T ?[?]( restrict volatile T *, ptrdiff_t );757 forall( type T ) lvalue _Atomic const restrict T ?[?]( _Atomic const restrict T *, ptrdiff_t );758 forall( type T ) lvalue _Atomic const volatile T ?[?]( _Atomic const volatile T *, ptrdiff_t );759 forall( type T ) lvalue _Atomic restrict volatile T ?[?]( _Atomic restrict volatile T *, ptrdiff_t );760 forall( type T ) lvalue const restrict volatile T ?[?]( const restrict volatile T *, ptrdiff_t );761 forall( type T ) lvalue _Atomic const restrict volatile T ?[?]( _Atomic const restrict volatile T *, ptrdiff_t );762 \end{lstlisting}763 \semantics764 The interpretations of subscript expressions are the interpretations of the corresponding function765 call expressions.766 \begin{rationale}767 C defines subscripting as pointer arithmetic in a way that makes \lstinline$a[i]$ and768 \lstinline$i[a]$ equivalent. \CFA provides the equivalence through a rewrite rule to reduce the769 number of overloadings of \lstinline$?[?]$.770 771 Subscript expressions are rewritten as function calls that pass the first parameter by value. This772 is somewhat unfortunate, since array-like types tend to be large. The alternative is to use the773 rewrite rule ``\lstinline$a[b]$ \rewrite \lstinline$?[?](&(a), b)$''. However, C semantics forbid774 this approach: the \lstinline$a$ in ``\lstinline$a[b]$'' can be an arbitrary pointer value, which775 does not have an address.776 777 The repetitive form of the predefined identifiers shows up a deficiency\index{deficiencies!pointers778 to qualified types} of \CFA's type system. Type qualifiers are not included in type values, so779 polymorphic functions that take pointers to arbitrary types often come in one flavor for each780 possible qualification of the pointed-at type.781 \end{rationale}782 783 784 \subsubsection{Function calls}785 786 \semantics787 A \define{function designator} is an interpretation of an expression that has function type. The788 \nonterm{postfix-expression} in a function call may have some interpretations that are function789 designators and some that are not.790 791 For those interpretations of the \nonterm{postfix-expression} that are not function designators, the792 expression is rewritten and becomes a call of a function named ``\lstinline$?()$''. The valid793 interpretations of the rewritten expression are determined in the manner described below.794 795 Each combination of function designators and argument interpretations is considered. For those796 interpretations of the \nonterm{postfix-expression} that are monomorphic\index{monomorphic function}797 function designators, the combination has a valid interpretation\index{valid interpretations} if the798 function designator accepts the number of arguments given, and each argument interpretation matches799 the corresponding explicit parameter:800 \begin{itemize}801 \item802 if the argument corresponds to a parameter in the function designator's prototype, the argument803 interpretation must have the same type as the corresponding parameter, or be implicitly convertible804 to the parameter's type805 \item806 if the function designator's type does not include a prototype or if the argument corresponds to807 ``\lstinline$...$'' in a prototype, a default argument promotion\index{default argument promotions}808 is applied to it.809 \end{itemize}810 The type of the valid interpretation is the return type of the function designator.811 812 For those combinations where the interpretation of the \nonterm{postfix-expression} is a813 polymorphic\index{polymorphic function} function designator and the function designator accepts the814 number of arguments given, there shall be at least one set of \define{implicit arguments} for the815 implicit parameters such that816 \begin{itemize}817 \item818 If the declaration of the implicit parameter uses type-class\index{type-class}819 \lstinline$type$\use{type}, the implicit argument must be an object type; if it uses820 \lstinline$dtype$, the implicit argument must be an object type or an incomplete type; and if it821 uses \lstinline$ftype$, the implicit argument must be a function type.822 823 \item824 if an explicit parameter's type uses any implicit parameters, then the corresponding explicit825 argument must have a type that is (or can be safely converted\index{safe conversions} to) the type826 produced by substituting the implicit arguments for the implicit parameters in the explicit827 parameter type.828 829 \item830 the remaining explicit arguments must match the remaining explicit parameters, as described for831 monomorphic function designators.832 833 \item834 for each assertion parameter\index{assertion parameters} in the function designator's type, there835 must be an object or function with the same identifier that is visible at the call site and whose836 type is compatible with or can be specialized to the type of the assertion declaration.837 \end{itemize}838 There is a valid interpretation for each such set of implicit parameters. The type of each valid839 interpretation is the return type of the function designator with implicit parameter values840 substituted for the implicit arguments.841 842 A valid interpretation is ambiguous\index{ambiguous interpretation} if the function designator or843 any of the argument interpretations is ambiguous.844 845 Every valid interpretation whose return type is not compatible with any other valid interpretation's846 return type is an interpretation of the function call expression.847 848 Every set of valid interpretations that have mutually compatible\index{compatible type} result types849 also produces an interpretation of the function call expression. The type of the interpretation is850 the composite\index{composite type} type of the types of the valid interpretations, and the value of851 the interpretation is that of the best valid interpretation\index{best valid interpretations}.852 \begin{rationale}853 One desirable property of a polymorphic programming language is \define{generalizability}: the854 ability to replace an abstraction with a more general but equivalent abstraction without requiring855 changes in any of the uses of the original\cite{Cormack90}. For instance, it should be possible to856 replace a function ``\lstinline$int f( int );$'' with ``\lstinline$forall( type T ) T f( T );$''857 without affecting any calls of \lstinline$f$.858 859 \CFA\index{deficiencies!generalizability} does not fully possess this property, because860 unsafe\index{unsafe conversions} conversions are not done when arguments are passed to polymorphic861 parameters. Consider862 \begin{lstlisting}863 float g( float, float );864 int i;865 float f;866 double d;867 f = g( f, f ); // (1)868 f = g( i, f ); // (2) (safe conversion to float)869 f = g( d, f ); // (3) (unsafe conversion to float)870 \end{lstlisting}871 If \lstinline$g$ was replaced by ``\lstinline$forall( type T ) T g( T, T );$'', the first and second872 calls would be unaffected, but the third would change: \lstinline$f$ would be converted to873 \lstinline$double$, and the result would be a \lstinline$double$.874 875 Another example is the function ``\lstinline$void h( int *);$''. This function can be passed a876 \lstinline$void *$ argument, but the generalization ``\lstinline$forall( type T ) void h( T *);$''877 can not. In this case, \lstinline$void$ is not a valid value for \lstinline$T$ because it is not an878 object type. If unsafe conversions were allowed, \lstinline$T$ could be inferred to be \emph{any}879 object type, which is undesirable.880 \end{rationale}881 882 \examples883 A function called ``\lstinline$?()$'' might be part of a numerical differentiation package.884 \begin{lstlisting}885 extern type Derivative;886 extern double ?()( Derivative, double );887 extern Derivative derivative_of( double (*f)( double ) );888 extern double sin( double );889 890 Derivative sin_dx = derivative_of( sin );891 double d;892 d = sin_dx( 12.9 );893 \end{lstlisting}894 Here, the only interpretation of \lstinline$sin_dx$ is as an object of type \lstinline$Derivative$.895 For that interpretation, the function call is treated as ``\lstinline$?()( sin_dx, 12.9 )$''.896 \begin{lstlisting}897 int f( long ); // (1)898 int f( int, int ); // (2)899 int f( int *); // (3)900 901 int i = f( 5 ); // calls (1)902 \end{lstlisting}903 Function (1) provides a valid interpretation of ``\lstinline$f( 5 )$'', using an implicit904 \lstinline$int$ to \lstinline$long$ conversion. The other functions do not, since the second905 requires two arguments, and since there is no implicit conversion from \lstinline$int$ to906 \lstinline$int *$ that could be used with the third function.907 908 \begin{lstlisting}909 forall( type T ) T h( T );910 double d = h( 1.5 );911 \end{lstlisting}912 ``\lstinline$1.5$'' is a \lstinline$double$ constant, so \lstinline$T$ is inferred to be913 \lstinline$double$, and the result of the function call is a \lstinline$double$.914 915 \begin{lstlisting}916 forall( type T, type U ) void g( T, U ); // (4)917 forall( type T ) void g( T, T ); // (5)918 forall( type T ) void g( T, long ); // (6)919 void g( long, long ); // (7)920 double d;921 int i;922 int *p;923 924 g( d, d ); // calls (5)925 g( d, i ); // calls (6)926 g( i, i ); // calls (7)927 g( i, p ); // calls (4)928 \end{lstlisting}929 The first call has valid interpretations for all four versions of \lstinline$g$. (6) and (7) are930 discarded because they involve unsafe \lstinline$double$-to-\lstinline$long$ conversions. (5) is931 chosen because it is less polymorphic than (4).932 933 For the second call, (7) is again discarded. Of the remaining interpretations for (4), (5), and (6)934 (with \lstinline$i$ converted to \lstinline$long$), (6) is chosen because it is the least935 polymorphic.936 937 The third call has valid interpretations for all of the functions; (7) is chosen since it is not938 polymorphic at all.939 940 The fourth call has no interpretation for (5), because its arguments must have compatible type. (4)941 is chosen because it does not involve unsafe conversions.942 \begin{lstlisting}943 forall( type T ) T min( T, T );944 double max( double, double );945 context min_max( T ) {@\impl{min_max}@946 T min( T, T );947 T max( T, T );948 }949 forall( type U | min_max( U ) ) void shuffle( U, U );950 shuffle(9, 10);951 \end{lstlisting}952 The only possibility for \lstinline$U$ is \lstinline$double$, because that is the type used in the953 only visible \lstinline$max$ function. 9 and 10 must be converted to \lstinline$double$, and954 \lstinline$min$ must be specialized with \lstinline$T$ bound to \lstinline$double$.955 \begin{lstlisting}956 extern void q( int ); // (8)957 extern void q( void * ); // (9)958 extern void r();959 q( 0 );960 r( 0 );961 \end{lstlisting}962 The \lstinline$int 0$ could be passed to (8), or the \lstinline$(void *)$963 specialization\index{specialization} of the null pointer\index{null pointer} \lstinline$0$\use{0}964 could be passed to (9). The former is chosen because the \lstinline$int$ \lstinline$0$ is less965 polymorphic\index{less polymorphic}. For the same reason, \lstinline$int$ \lstinline$0$ is passed966 to \lstinline$r()$, even though it has \emph{no} declared parameter types.967 968 969 \subsubsection{Structure and union members}970 971 \semantics In the member selection expression ``\lstinline$s$.\lstinline$m$'', there shall be at972 least one interpretation of \lstinline$s$ whose type is a structure type or union type containing a973 member named \lstinline$m$. If two or more interpretations of \lstinline$s$ have members named974 \lstinline$m$ with mutually compatible types, then the expression has an ambiguous975 interpretation\index{ambiguous interpretation} whose type is the composite type of the types of the976 members. If an interpretation of \lstinline$s$ has a member \lstinline$m$ whose type is not977 compatible with any other \lstinline$s$'s \lstinline$m$, then the expression has an interpretation978 with the member's type. The expression has no other interpretations.979 980 The expression ``\lstinline$p->m$'' has the same interpretations as the expression981 ``\lstinline$(*p).m$''.982 983 984 \subsubsection{Postfix increment and decrement operators}985 986 \begin{lstlisting}987 _Bool ?++( volatile _Bool * ),988 ?++( _Atomic volatile _Bool * );989 char ?++( volatile char * ),990 ?++( _Atomic volatile char * );991 signed char ?++( volatile signed char * ),992 ?++( _Atomic volatile signed char * );993 unsigned char ?++( volatile signed char * ),994 ?++( _Atomic volatile signed char * );995 short int ?++( volatile short int * ),996 ?++( _Atomic volatile short int * );997 unsigned short int ?++( volatile unsigned short int * ),998 ?++( _Atomic volatile unsigned short int * );999 int ?++( volatile int * ),1000 ?++( _Atomic volatile int * );1001 unsigned int ?++( volatile unsigned int * ),1002 ?++( _Atomic volatile unsigned int * );1003 long int ?++( volatile long int * ),1004 ?++( _Atomic volatile long int * );1005 long unsigned int ?++( volatile long unsigned int * ),1006 ?++( _Atomic volatile long unsigned int * );1007 long long int ?++( volatile long long int * ),1008 ?++( _Atomic volatile long long int * );1009 long long unsigned ?++( volatile long long unsigned int * ),1010 ?++( _Atomic volatile long long unsigned int * );1011 float ?++( volatile float * ),1012 ?++( _Atomic volatile float * );1013 double ?++( volatile double * ),1014 ?++( _Atomic volatile double * );1015 long double ?++( volatile long double * ),1016 ?++( _Atomic volatile long double * );1017 1018 forall( type T ) T * ?++( T * restrict volatile * ),1019 * ?++( T * _Atomic restrict volatile * );1020 1021 forall( type T ) _Atomic T * ?++( _Atomic T * restrict volatile * ),1022 * ?++( _Atomic T * _Atomic restrict volatile * );1023 1024 forall( type T ) const T * ?++( const T * restrict volatile * ),1025 * ?++( const T * _Atomic restrict volatile * );1026 1027 forall( type T ) volatile T * ?++( volatile T * restrict volatile * ),1028 * ?++( volatile T * _Atomic restrict volatile * );1029 1030 forall( type T ) restrict T * ?++( restrict T * restrict volatile * ),1031 * ?++( restrict T * _Atomic restrict volatile * );1032 1033 forall( type T ) _Atomic const T * ?++( _Atomic const T * restrict volatile * ),1034 * ?++( _Atomic const T * _Atomic restrict volatile * );1035 1036 forall( type T ) _Atomic restrict T * ?++( _Atomic restrict T * restrict volatile * ),1037 * ?++( _Atomic restrict T * _Atomic restrict volatile * );1038 1039 forall( type T ) _Atomic volatile T * ?++( _Atomic volatile T * restrict volatile * ),1040 * ?++( _Atomic volatile T * _Atomic restrict volatile * );1041 1042 forall( type T ) const restrict T * ?++( const restrict T * restrict volatile * ),1043 * ?++( const restrict T * _Atomic restrict volatile * );1044 1045 forall( type T ) const volatile T * ?++( const volatile T * restrict volatile * ),1046 * ?++( const volatile T * _Atomic restrict volatile * );1047 1048 forall( type T ) restrict volatile T * ?++( restrict volatile T * restrict volatile * ),1049 * ?++( restrict volatile T * _Atomic restrict volatile * );1050 1051 forall( type T ) _Atomic const restrict T * ?++( _Atomic const restrict T * restrict volatile * ),1052 * ?++( _Atomic const restrict T * _Atomic restrict volatile * );1053 1054 forall( type T ) _Atomic const volatile T * ?++( _Atomic const volatile T * restrict volatile * ),1055 * ?++( _Atomic const volatile T * _Atomic restrict volatile * );1056 1057 forall( type T ) _Atomic restrict volatile T * ?++( _Atomic restrict volatile T * restrict volatile * ),1058 * ?++( _Atomic restrict volatile T * _Atomic restrict volatile * );1059 1060 forall( type T ) const restrict volatile T * ?++( const restrict volatile T * restrict volatile * ),1061 * ?++( const restrict volatile T * _Atomic restrict volatile * );1062 1063 forall( type T ) _Atomic const restrict volatile T * ?++( _Atomic const restrict volatile T * restrict volatile * ),1064 * ?++( _Atomic const restrict volatile T * _Atomic restrict volatile * );1065 1066 _Bool ?--( volatile _Bool * ),1067 ?--( _Atomic volatile _Bool * );1068 char ?--( volatile char * ),1069 ?--( _Atomic volatile char * );1070 signed char ?--( volatile signed char * ),1071 ?--( _Atomic volatile signed char * );1072 unsigned char ?--( volatile signed char * ),1073 ?--( _Atomic volatile signed char * );1074 short int ?--( volatile short int * ),1075 ?--( _Atomic volatile short int * );1076 unsigned short int ?--( volatile unsigned short int * ),1077 ?--( _Atomic volatile unsigned short int * );1078 int ?--( volatile int * ),1079 ?--( _Atomic volatile int * );1080 unsigned int ?--( volatile unsigned int * ),1081 ?--( _Atomic volatile unsigned int * );1082 long int ?--( volatile long int * ),1083 ?--( _Atomic volatile long int * );1084 long unsigned int ?--( volatile long unsigned int * ),1085 ?--( _Atomic volatile long unsigned int * );1086 long long int ?--( volatile long long int * ),1087 ?--( _Atomic volatile long long int * );1088 long long unsigned ?--( volatile long long unsigned int * ),1089 ?--( _Atomic volatile long long unsigned int * );1090 float ?--( volatile float * ),1091 ?--( _Atomic volatile float * );1092 double ?--( volatile double * ),1093 ?--( _Atomic volatile double * );1094 long double ?--( volatile long double * ),1095 ?--( _Atomic volatile long double * );1096 1097 forall( type T ) T * ?--( T * restrict volatile * ),1098 * ?--( T * _Atomic restrict volatile * );1099 1100 forall( type T ) _Atomic T * ?--( _Atomic T * restrict volatile * ),1101 * ?--( _Atomic T * _Atomic restrict volatile * );1102 1103 forall( type T ) const T * ?--( const T * restrict volatile * ),1104 * ?--( const T * _Atomic restrict volatile * );1105 1106 forall( type T ) volatile T * ?--( volatile T * restrict volatile * ),1107 * ?--( volatile T * _Atomic restrict volatile * );1108 1109 forall( type T ) restrict T * ?--( restrict T * restrict volatile * ),1110 * ?--( restrict T * _Atomic restrict volatile * );1111 1112 forall( type T ) _Atomic const T * ?--( _Atomic const T * restrict volatile * ),1113 * ?--( _Atomic const T * _Atomic restrict volatile * );1114 1115 forall( type T ) _Atomic restrict T * ?--( _Atomic restrict T * restrict volatile * ),1116 * ?--( _Atomic restrict T * _Atomic restrict volatile * );1117 1118 forall( type T ) _Atomic volatile T * ?--( _Atomic volatile T * restrict volatile * ),1119 * ?--( _Atomic volatile T * _Atomic restrict volatile * );1120 1121 forall( type T ) const restrict T * ?--( const restrict T * restrict volatile * ),1122 * ?--( const restrict T * _Atomic restrict volatile * );1123 1124 forall( type T ) const volatile T * ?--( const volatile T * restrict volatile * ),1125 * ?--( const volatile T * _Atomic restrict volatile * );1126 1127 forall( type T ) restrict volatile T * ?--( restrict volatile T * restrict volatile * ),1128 * ?--( restrict volatile T * _Atomic restrict volatile * );1129 1130 forall( type T ) _Atomic const restrict T * ?--( _Atomic const restrict T * restrict volatile * ),1131 * ?--( _Atomic const restrict T * _Atomic restrict volatile * );1132 1133 forall( type T ) _Atomic const volatile T * ?--( _Atomic const volatile T * restrict volatile * ),1134 * ?--( _Atomic const volatile T * _Atomic restrict volatile * );1135 1136 forall( type T ) _Atomic restrict volatile T * ?--( _Atomic restrict volatile T * restrict volatile * ),1137 * ?--( _Atomic restrict volatile T * _Atomic restrict volatile * );1138 1139 forall( type T ) const restrict volatile T * ?--( const restrict volatile T * restrict volatile * ),1140 * ?--( const restrict volatile T * _Atomic restrict volatile * );1141 1142 forall( type T ) _Atomic const restrict volatile T * ?--( _Atomic const restrict volatile T * restrict volatile * ),1143 * ?--( _Atomic const restrict volatile T * _Atomic restrict volatile * );1144 \end{lstlisting}1145 For every extended integer type \lstinline$X$ there exist1146 % Don't use predefined: keep this out of prelude.cf.1147 \begin{lstlisting}1148 X ?++( volatile X * ), ?++( _Atomic volatile X * ),1149 ?--( volatile X * ), ?--( _Atomic volatile X * );1150 \end{lstlisting}1151 For every complete enumerated type \lstinline$E$ there exist1152 % Don't use predefined: keep this out of prelude.cf.1153 \begin{lstlisting}1154 E ?++( volatile E * ), ?++( _Atomic volatile E * ),1155 ?--( volatile E * ), ?--( _Atomic volatile E * );1156 \end{lstlisting}1157 1158 \begin{rationale}1159 Note that ``\lstinline$++$'' and ``\lstinline$--$'' are rewritten as function calls that are given a1160 pointer to that operand. (This is true of all operators that modify an operand.) As Hamish Macdonald1161 has pointed out, this forces the modified operand of such expressions to be an lvalue. This1162 partially enforces the C semantic rule that such operands must be \emph{modifiable} lvalues.1163 \end{rationale}1164 1165 \begin{rationale}1166 In C, a semantic rule requires that pointer operands of increment and decrement be pointers to1167 object types. Hence, \lstinline$void *$ objects cannot be incremented. In \CFA, the restriction1168 follows from the use of a \lstinline$type$ parameter in the predefined function definitions, as1169 opposed to \lstinline$dtype$, since only object types can be inferred arguments corresponding to the1170 type parameter \lstinline$T$.1171 \end{rationale}1172 1173 \semantics1174 First, each interpretation of the operand of an increment or decrement expression is considered1175 separately. For each interpretation that is a bit-field or is declared with the1176 \lstinline$register$\index{register@{\lstinline$register$}} storage-class1177 specifier\index{storage-class specifier}, the expression has one valid interpretation, with the type1178 of the operand, and the expression is ambiguous if the operand is.1179 1180 For the remaining interpretations, the expression is rewritten, and the interpretations of the1181 expression are the interpretations of the corresponding function call. Finally, all interpretations1182 of the expression produced for the different interpretations of the operand are combined to produce1183 the interpretations of the expression as a whole; where interpretations have compatible result1184 types, the best interpretations are selected in the manner described for function call expressions.1185 1186 \examples1187 \begin{lstlisting}1188 volatile short int vs; vs++; // rewritten as ?++( &(vs) )1189 short int s; s++;1190 const short int cs; cs++;1191 _Atomic short int as; as++;1192 \end{lstlisting}1193 \begin{sloppypar}1194 Since \lstinline$&(vs)$ has type \lstinline$volatile short int *$, the best valid interpretation of1195 \lstinline$vs++$ calls the \lstinline$?++$ function with the \lstinline$volatile short *$ parameter.1196 \lstinline$s++$ does the same, applying the safe conversion from \lstinline$short int *$ to1197 \lstinline$volatile short int *$. Note that there is no conversion that adds an \lstinline$_Atomic$1198 qualifier, so the \lstinline$_Atomic volatile short int$ overloading does not provide a valid1199 interpretation.1200 \end{sloppypar}1201 1202 There is no safe conversion from \lstinline$const short int *$ to \lstinline$volatile short int *$,1203 and no \lstinline$?++$ function that accepts a \lstinline$const *$ parameter, so \lstinline$cs++$1204 has no valid interpretations.1205 1206 The best valid interpretation of \lstinline$as++$ calls the \lstinline$short ?++$ function with the1207 \lstinline$_Atomic volatile short int *$ parameter, applying a safe conversion to add the1208 \lstinline$volatile$ qualifier.1209 1210 \begin{lstlisting}1211 char * const restrict volatile * restrict volatile pqpc; pqpc++1212 char * * restrict volatile ppc; ppc++;1213 \end{lstlisting}1214 Since \lstinline$&(pqpc)$ has type \lstinline$char * const restrict volatile * restrict volatile *$,1215 the best valid interpretation of \lstinline$pqpc++$ calls the polymorphic \lstinline$?++$ function1216 with the \lstinline$const restrict volatile T * restrict volatile *$ parameter, inferring1217 \lstinline$T$ to be \lstinline$char *$.1218 1219 \begin{sloppypar}1220 \lstinline$ppc++$ calls the same function, again inferring \lstinline$T$ to be \lstinline$char *$,1221 and using the safe conversions from \lstinline$T$ to \lstinline$T const restrict volatile$.1222 \end{sloppypar}1223 1224 \begin{rationale}1225 Increment and decrement expressions show up a deficiency of \CFA's type system. There is no such1226 thing as a pointer to a register object or bit-field\index{deficiencies!pointers to bit-fields}.1227 Therefore, there is no way to define a function that alters them, and hence no way to define1228 increment and decrement functions for them. As a result, the semantics of increment and decrement1229 expressions must treat them specially. This holds true for all of the operators that may modify1230 such objects.1231 \end{rationale}1232 1233 \begin{rationale}1234 The polymorphic overloadings for pointer increment and decrement can be understood by considering1235 increasingly complex types.1236 \begin{enumerate}1237 \item1238 ``\lstinline$char * p; p++;$''. The argument to \lstinline$?++$ has type \lstinline$char * *$, and1239 the result has type \lstinline$char *$. The expression would be valid if \lstinline$?++$ were1240 declared by1241 \begin{lstlisting}1242 forall( type T ) T * ?++( T * * );1243 \end{lstlisting}1244 with \lstinline$T$ inferred to be \lstinline$char$.1245 1246 \item1247 ``\lstinline$char *restrict volatile qp; qp++$''. The result again has type \lstinline$char *$, but1248 the argument now has type \lstinline$char *restrict volatile *$, so it cannot be passed to the1249 hypothetical function declared in point 1. Hence the actual predefined function is1250 \begin{lstlisting}1251 forall( type T ) T * ?++( T * restrict volatile * );1252 \end{lstlisting}1253 which also accepts a \lstinline$char * *$ argument, because of the safe conversions that add1254 \lstinline$volatile$ and \lstinline$restrict$ qualifiers. (The parameter is not const-qualified, so1255 constant pointers cannot be incremented.)1256 1257 \item1258 ``\lstinline$char *_Atomic ap; ap++$''. The result again has type \lstinline$char *$, but no safe1259 conversion adds an \lstinline$_Atomic$ qualifier, so the function in point 2 is not applicable. A1260 separate overloading of \lstinline$?++$ is required.1261 1262 \item1263 ``\lstinline$char const volatile * pq; pq++$''. Here the result has type1264 \lstinline$char const volatile *$, so a new overloading is needed:1265 \begin{lstlisting}1266 forall( type T ) T const volatile * ?++( T const volatile *restrict volatile * );1267 \end{lstlisting}1268 One overloading is needed for each combination of qualifiers in the pointed-at1269 type\index{deficiencies!pointers to qualified types}.1270 1271 \item1272 ``\lstinline$float *restrict * prp; prp++$''. The \lstinline$restrict$ qualifier is handled just1273 like \lstinline$const$ and \lstinline$volatile$ in the previous case:1274 \begin{lstlisting}1275 forall( type T ) T restrict * ?++( T restrict *restrict volatile * );1276 \end{lstlisting}1277 with \lstinline$T$ inferred to be \lstinline$float *$. This looks odd, because {\c11} contains a1278 constraint that requires restrict-qualified types to be pointer-to-object types, and \lstinline$T$1279 is not syntactically a pointer type. \CFA loosens the constraint.1280 \end{enumerate}1281 \end{rationale}1282 1283 1284 \subsubsection{Compound literals}1285 1286 \semantics1287 A compound literal has one interpretation, with the type given by the \nonterm{type-name} of the1288 compound literal.1289 1290 1291 \subsection{Unary operators}1292 1293 \begin{syntax}1294 \lhs{unary-expression}1295 \rhs \nonterm{postfix-expression}1296 \rhs \lstinline$++$ \nonterm{unary-expression}1297 \rhs \lstinline$--$ \nonterm{unary-expression}1298 \rhs \nonterm{unary-operator} \nonterm{cast-expression}1299 \rhs \lstinline$sizeof$ \nonterm{unary-expression}1300 \rhs \lstinline$sizeof$ \lstinline$($ \nonterm{type-name} \lstinline$)$1301 \lhs{unary-operator} one of \rhs \lstinline$&$ \lstinline$*$ \lstinline$+$ \lstinline$-$ \lstinline$~$ \lstinline$!$1302 \end{syntax}1303 1304 \rewriterules1305 \begin{lstlisting}1306 *a @\rewrite@ *?(a) @\use{*?}@1307 +a @\rewrite@ +?(a) @\use{+?}@1308 -a @\rewrite@ -?(a) @\use{-?}@1309 ~a @\rewrite@ ~?(a) @\use{~?}@1310 !a @\rewrite@ !?(a) @\use{"!?}@1311 ++a @\rewrite@ ++?(&(a)) @\use{++?}@1312 --a @\rewrite@ --?(&(a)) @\use{--?}@1313 \end{lstlisting}1314 1315 1316 \subsubsection{Prefix increment and decrement operators}1317 1318 \begin{lstlisting}1319 _Bool ++?( volatile _Bool * ),1320 ++?( _Atomic volatile _Bool * );1321 char ++?( volatile char * ),1322 ++?( _Atomic volatile char * );1323 signed char ++?( volatile signed char * ),1324 ++?( _Atomic volatile signed char * );1325 unsigned char ++?( volatile signed char * ),1326 ++?( _Atomic volatile signed char * );1327 short int ++?( volatile short int * ),1328 ++?( _Atomic volatile short int * );1329 unsigned short int ++?( volatile unsigned short int * ),1330 ++?( _Atomic volatile unsigned short int * );1331 int ++?( volatile int * ),1332 ++?( _Atomic volatile int * );1333 unsigned int ++?( volatile unsigned int * ),1334 ++?( _Atomic volatile unsigned int * );1335 long int ++?( volatile long int * ),1336 ++?( _Atomic volatile long int * );1337 long unsigned int ++?( volatile long unsigned int * ),1338 ++?( _Atomic volatile long unsigned int * );1339 long long int ++?( volatile long long int * ),1340 ++?( _Atomic volatile long long int * );1341 long long unsigned ++?( volatile long long unsigned int * ),1342 ++?( _Atomic volatile long long unsigned int * );1343 float ++?( volatile float * ),1344 ++?( _Atomic volatile float * );1345 double ++?( volatile double * ),1346 ++?( _Atomic volatile double * );1347 long double ++?( volatile long double * ),1348 ++?( _Atomic volatile long double * );1349 1350 forall( type T ) T * ++?( T * restrict volatile * ),1351 * ++?( T * _Atomic restrict volatile * );1352 1353 forall( type T ) _Atomic T * ++?( _Atomic T * restrict volatile * ),1354 * ++?( _Atomic T * _Atomic restrict volatile * );1355 1356 forall( type T ) const T * ++?( const T * restrict volatile * ),1357 * ++?( const T * _Atomic restrict volatile * );1358 1359 forall( type T ) volatile T * ++?( volatile T * restrict volatile * ),1360 * ++?( volatile T * _Atomic restrict volatile * );1361 1362 forall( type T ) restrict T * ++?( restrict T * restrict volatile * ),1363 * ++?( restrict T * _Atomic restrict volatile * );1364 1365 forall( type T ) _Atomic const T * ++?( _Atomic const T * restrict volatile * ),1366 * ++?( _Atomic const T * _Atomic restrict volatile * );1367 1368 forall( type T ) _Atomic volatile T * ++?( _Atomic volatile T * restrict volatile * ),1369 * ++?( _Atomic volatile T * _Atomic restrict volatile * );1370 1371 forall( type T ) _Atomic restrict T * ++?( _Atomic restrict T * restrict volatile * ),1372 * ++?( _Atomic restrict T * _Atomic restrict volatile * );1373 1374 forall( type T ) const volatile T * ++?( const volatile T * restrict volatile * ),1375 * ++?( const volatile T * _Atomic restrict volatile * );1376 1377 forall( type T ) const restrict T * ++?( const restrict T * restrict volatile * ),1378 * ++?( const restrict T * _Atomic restrict volatile * );1379 1380 forall( type T ) restrict volatile T * ++?( restrict volatile T * restrict volatile * ),1381 * ++?( restrict volatile T * _Atomic restrict volatile * );1382 1383 forall( type T ) _Atomic const volatile T * ++?( _Atomic const volatile T * restrict volatile * ),1384 * ++?( _Atomic const volatile T * _Atomic restrict volatile * );1385 1386 forall( type T ) _Atomic const restrict T * ++?( _Atomic const restrict T * restrict volatile * ),1387 * ++?( _Atomic const restrict T * _Atomic restrict volatile * );1388 1389 forall( type T ) _Atomic restrict volatile T * ++?( _Atomic restrict volatile T * restrict volatile * ),1390 * ++?( _Atomic restrict volatile T * _Atomic restrict volatile * );1391 1392 forall( type T ) const restrict volatile T * ++?( const restrict volatile T * restrict volatile * ),1393 * ++?( const restrict volatile T * _Atomic restrict volatile * );1394 1395 forall( type T ) _Atomic const restrict volatile T * ++?( _Atomic const restrict volatile T * restrict volatile * ),1396 * ++?( _Atomic const restrict volatile T * _Atomic restrict volatile * );1397 1398 _Bool --?( volatile _Bool * ),1399 --?( _Atomic volatile _Bool * );1400 char --?( volatile char * ),1401 --?( _Atomic volatile char * );1402 signed char --?( volatile signed char * ),1403 --?( _Atomic volatile signed char * );1404 unsigned char --?( volatile signed char * ),1405 --?( _Atomic volatile signed char * );1406 short int --?( volatile short int * ),1407 --?( _Atomic volatile short int * );1408 unsigned short int --?( volatile unsigned short int * ),1409 --?( _Atomic volatile unsigned short int * );1410 int --?( volatile int * ),1411 --?( _Atomic volatile int * );1412 unsigned int --?( volatile unsigned int * ),1413 --?( _Atomic volatile unsigned int * );1414 long int --?( volatile long int * ),1415 --?( _Atomic volatile long int * );1416 long unsigned int --?( volatile long unsigned int * ),1417 --?( _Atomic volatile long unsigned int * );1418 long long int --?( volatile long long int * ),1419 --?( _Atomic volatile long long int * );1420 long long unsigned --?( volatile long long unsigned int * ),1421 --?( _Atomic volatile long long unsigned int * );1422 float --?( volatile float * ),1423 --?( _Atomic volatile float * );1424 double --?( volatile double * ),1425 --?( _Atomic volatile double * );1426 long double --?( volatile long double * ),1427 --?( _Atomic volatile long double * );1428 1429 forall( type T ) T * --?( T * restrict volatile * ),1430 * --?( T * _Atomic restrict volatile * );1431 1432 forall( type T ) _Atomic T * --?( _Atomic T * restrict volatile * ),1433 * --?( _Atomic T * _Atomic restrict volatile * );1434 1435 forall( type T ) const T * --?( const T * restrict volatile * ),1436 * --?( const T * _Atomic restrict volatile * );1437 1438 forall( type T ) volatile T * --?( volatile T * restrict volatile * ),1439 * --?( volatile T * _Atomic restrict volatile * );1440 1441 forall( type T ) restrict T * --?( restrict T * restrict volatile * ),1442 * --?( restrict T * _Atomic restrict volatile * );1443 1444 forall( type T ) _Atomic const T * --?( _Atomic const T * restrict volatile * ),1445 * --?( _Atomic const T * _Atomic restrict volatile * );1446 1447 forall( type T ) _Atomic volatile T * --?( _Atomic volatile T * restrict volatile * ),1448 * --?( _Atomic volatile T * _Atomic restrict volatile * );1449 1450 forall( type T ) _Atomic restrict T * --?( _Atomic restrict T * restrict volatile * ),1451 * --?( _Atomic restrict T * _Atomic restrict volatile * );1452 1453 forall( type T ) const volatile T * --?( const volatile T * restrict volatile * ),1454 * --?( const volatile T * _Atomic restrict volatile * );1455 1456 forall( type T ) const restrict T * --?( const restrict T * restrict volatile * ),1457 * --?( const restrict T * _Atomic restrict volatile * );1458 1459 forall( type T ) restrict volatile T * --?( restrict volatile T * restrict volatile * ),1460 * --?( restrict volatile T * _Atomic restrict volatile * );1461 1462 forall( type T ) _Atomic const volatile T * --?( _Atomic const volatile T * restrict volatile * ),1463 * --?( _Atomic const volatile T * _Atomic restrict volatile * );1464 1465 forall( type T ) _Atomic const restrict T * --?( _Atomic const restrict T * restrict volatile * ),1466 * --?( _Atomic const restrict T * _Atomic restrict volatile * );1467 1468 forall( type T ) _Atomic restrict volatile T * --?( _Atomic restrict volatile T * restrict volatile * ),1469 * --?( _Atomic restrict volatile T * _Atomic restrict volatile * );1470 1471 forall( type T ) const restrict volatile T * --?( const restrict volatile T * restrict volatile * ),1472 * --?( const restrict volatile T * _Atomic restrict volatile * );1473 1474 forall( type T ) _Atomic const restrict volatile T * --?( _Atomic const restrict volatile T * restrict volatile * ),1475 * --?( _Atomic const restrict volatile T * _Atomic restrict volatile * );1476 \end{lstlisting}1477 For every extended integer type \lstinline$X$ there exist1478 % Don't use predefined: keep this out of prelude.cf.1479 \begin{lstlisting}1480 X ++?( volatile X * ),1481 ++?( _Atomic volatile X * ),1482 --?( volatile X * ),1483 --?( _Atomic volatile X * );1484 \end{lstlisting}1485 For every complete enumerated type \lstinline$E$ there exist1486 % Don't use predefined: keep this out of prelude.cf.1487 \begin{lstlisting}1488 E ++?( volatile E * ),1489 ++?( _Atomic volatile E * ),1490 ?--( volatile E * ),1491 ?--( _Atomic volatile E * );1492 \end{lstlisting}1493 1494 \semantics1495 The interpretations of prefix increment and decrement expressions are1496 determined in the same way as the interpretations of postfix increment and1497 decrement expressions.1498 1499 1500 \subsubsection{Address and indirection operators}1501 1502 \begin{lstlisting}1503 forall( type T ) lvalue T *?( T * );1504 forall( type T ) _Atomic lvalue T *?( _Atomic T * );1505 forall( type T ) const lvalue T *?( const T * );1506 forall( type T ) volatile lvalue T *?( volatile T * );1507 forall( type T ) restrict lvalue T *?( restrict T * );1508 forall( type T ) _Atomic const lvalue T *?( _Atomic const T * );1509 forall( type T ) _Atomic volatile lvalue T *?( _Atomic volatile T * );1510 forall( type T ) _Atomic restrict lvalue T *?( _Atomic restrict T * );1511 forall( type T ) const volatile lvalue T *?( const volatile T * );1512 forall( type T ) const restrict lvalue T *?( const restrict T * );1513 forall( type T ) restrict volatile lvalue T *?( restrict volatile T * );1514 forall( type T ) _Atomic const volatile lvalue T *?( _Atomic const volatile T * );1515 forall( type T ) _Atomic const restrict lvalue T *?( _Atomic const restrict T * );1516 forall( type T ) _Atomic restrict volatile lvalue T *?( _Atomic restrict volatile T * );1517 forall( type T ) const restrict volatile lvalue T *?( const restrict volatile T * );1518 forall( type T ) _Atomic const restrict volatile lvalue T *?( _Atomic const restrict volatile T * );1519 1520 forall( ftype FT ) FT *?( FT * );1521 \end{lstlisting}1522 1523 \constraints1524 The operand of the unary ``\lstinline$&$'' operator shall have exactly one1525 interpretation\index{ambiguous interpretation}\index{interpretations}, which shall be unambiguous.1526 1527 \semantics1528 The ``\lstinline$&$'' expression has one interpretation which is of type \lstinline$T *$, where1529 \lstinline$T$ is the type of the operand.1530 1531 The interpretations of an indirection expression are the interpretations of the corresponding1532 function call.1533 1534 1535 \subsubsection{Unary arithmetic operators}1536 1537 \begin{lstlisting}1538 int1539 +?( int ),1540 -?( int ),1541 ~?( int );1542 unsigned int1543 +?( unsigned int ),1544 -?( unsigned int ),1545 ~?( unsigned int );1546 long int1547 +?( long int ),1548 -?( long int ),1549 ~?( long int );1550 long unsigned int1551 +?( long unsigned int ),1552 -?( long unsigned int ),1553 ~?( long unsigned int );1554 long long int1555 +?( long long int ),1556 -?( long long int ),1557 ~?( long long int );1558 long long unsigned int1559 +?( long long unsigned int ),1560 -?( long long unsigned int ),1561 ~?( long long unsigned int );1562 float1563 +?( float ),1564 -?( float );1565 double1566 +?( double ),1567 -?( double );1568 long double1569 +?( long double ),1570 -?( long double );1571 _Complex float1572 +?( _Complex float ),1573 -?( _Complex float );1574 _Complex double1575 +?( _Complex double ),1576 -?( _Complex double );1577 _Complex long double1578 +?( _Complex long double ),1579 -?( _Complex long double );1580 1581 int !?( int ),1582 !?( unsigned int ),1583 !?( long ),1584 !?( long unsigned int ),1585 !?( long long int ),1586 !?( long long unsigned int ),1587 !?( float ),1588 !?( double ),1589 !?( long double ),1590 !?( _Complex float ),1591 !?( _Complex double ),1592 !?( _Complex long double );1593 1594 forall( dtype DT ) int !?( const restrict volatile DT * );1595 forall( dtype DT ) int !?( _Atomic const restrict volatile DT * );1596 forall( ftype FT ) int !?( FT * );1597 \end{lstlisting}1598 For every extended integer type \lstinline$X$ with integer conversion rank \index{integer conversion1599 rank}greater than the rank of \lstinline$int$ there exist1600 % Don't use predefined: keep this out of prelude.cf.1601 \begin{lstlisting}1602 X +?( X ), -?( X ), ~?( X );1603 int !?( X );1604 \end{lstlisting}1605 1606 \semantics1607 The interpretations of a unary arithmetic expression are the interpretations of the corresponding1608 function call.1609 1610 \examples1611 \begin{lstlisting}1612 long int li;1613 void eat_double( double );@\use{eat_double}@1614 1615 eat_double(-li ); // @\rewrite@ eat_double( -?( li ) );1616 \end{lstlisting}1617 The valid interpretations of ``\lstinline$-li$'' (assuming no extended integer types exist) are1618 \begin{center}1619 \begin{tabular}{llc}1620 interpretation & result type & expression conversion cost \\1621 \hline1622 \lstinline$-?( (int)li )$ & \lstinline$int$ & (unsafe) \\1623 \lstinline$-?( (unsigned)li)$ & \lstinline$unsigned int$ & (unsafe) \\1624 \lstinline$-?( (long)li)$ & \lstinline$long$ & 0 \\1625 \lstinline$-?( (long unsigned int)li)$ & \lstinline$long unsigned int$ & 1 \\1626 \lstinline$-?( (long long int)li)$ & \lstinline$long long int$ & 2 \\1627 \lstinline$-?( (long long unsigned int)li)$ & \lstinline$long long unsigned int$& 3 \\1628 \lstinline$-?( (float)li)$ & \lstinline$float$ & 4 \\1629 \lstinline$-?( (double)li)$ & \lstinline$double$ & 5 \\1630 \lstinline$-?( (long double)li)$ & \lstinline$long double$ & 6 \\1631 \lstinline$-?( (_Complex float)li)$ & \lstinline$float$ & (unsafe) \\1632 \lstinline$-?( (_Complex double)li)$ & \lstinline$double$ & (unsafe) \\1633 \lstinline$-?( (_Complex long double)li)$ & \lstinline$long double$ & (unsafe) \\1634 \end{tabular}1635 \end{center}1636 The valid interpretations of the \lstinline$eat_double$ call, with the cost of the argument1637 conversion and the cost of the entire expression, are1638 \begin{center}1639 \begin{tabular}{lcc}1640 interpretation & argument cost & expression cost \\1641 \hline1642 \lstinline$eat_double( (double)-?( (int)li) )$ & 7 & (unsafe) \\1643 \lstinline$eat_double( (double)-?( (unsigned)li) )$ & 6 & (unsafe) \\1644 \lstinline$eat_double( (double)-?(li) )$ & 5 & \(0+5=5\) \\1645 \lstinline$eat_double( (double)-?( (long unsigned int)li) )$ & 4 & \(1+4=5\) \\1646 \lstinline$eat_double( (double)-?( (long long int)li) )$ & 3 & \(2+3=5\) \\1647 \lstinline$eat_double( (double)-?( (long long unsigned int)li) )$& 2 & \(3+2=5\) \\1648 \lstinline$eat_double( (double)-?( (float)li) )$ & 1 & \(4+1=5\) \\1649 \lstinline$eat_double( (double)-?( (double)li) )$ & 0 & \(5+0=5\) \\1650 \lstinline$eat_double( (double)-?( (long double)li) )$ & (unsafe) & (unsafe) \\1651 \lstinline$eat_double( (double)-?( (_Complex float)li) )$ & (unsafe) & (unsafe) \\1652 \lstinline$eat_double( (double)-?( (_Complex double)li) )$ & (unsafe) & (unsafe) \\1653 \lstinline$eat_double( (double)-?( (_Complex long double)li) )$ & (unsafe) & (unsafe) \\1654 \end{tabular}1655 \end{center}1656 Each has result type \lstinline$void$, so the best must be selected. The interpretations involving1657 unsafe conversions are discarded. The remainder have equal expression conversion costs, so the1658 ``highest argument conversion cost'' rule is invoked, and the chosen interpretation is1659 \lstinline$eat_double( (double)-?(li) )$.1660 1661 1662 \subsubsection{The {\tt sizeof} and {\tt \_Alignof} operators}1663 1664 \constraints1665 The operand of \lstinline$sizeof$ or \lstinline$_Alignof$ shall not be \lstinline$type$,1666 \lstinline$dtype$, or \lstinline$ftype$.1667 1668 When the \lstinline$sizeof$\use{sizeof} operator is applied to an expression, the expression shall1669 have exactly one interpretation\index{ambiguous interpretation}\index{interpretations}, which shall1670 be unambiguous. \semantics A \lstinline$sizeof$ or \lstinline$_Alignof$ expression has one1671 interpretation, of type \lstinline$size_t$.1672 1673 When \lstinline$sizeof$ is applied to an identifier declared by a \nonterm{type-declaration} or a1674 \nonterm{type-parameter}, it yields the size in bytes of the type that implements the operand. When1675 the operand is an opaque type or an inferred type parameter\index{inferred parameter}, the1676 expression is not a constant expression.1677 1678 When \lstinline$_Alignof$ is applied to an identifier declared by a \nonterm{type-declaration} or a1679 \nonterm{type-parameter}, it yields the alignment requirement of the type that implements the1680 operand. When the operand is an opaque type or an inferred type parameter\index{inferred1681 parameter}, the expression is not a constant expression.1682 \begin{rationale}1683 \begin{lstlisting}1684 type Pair = struct { int first, second; };1685 size_t p_size = sizeof(Pair); // constant expression1686 1687 extern type Rational;@\use{Rational}@1688 size_t c_size = sizeof(Rational); // non-constant expression1689 1690 forall(type T) T f(T p1, T p2) {1691 size_t t_size = sizeof(T); // non-constant expression1692 ...1693 }1694 \end{lstlisting}1695 ``\lstinline$sizeof Rational$'', although not statically known, is fixed. Within \lstinline$f()$,1696 ``\lstinline$sizeof(T)$'' is fixed for each call of \lstinline$f()$, but may vary from call to call.1697 \end{rationale}1698 1699 \subsection{Cast operators}1700 \begin{syntax}1701 \lhs{cast-expression}1702 \rhs \nonterm{unary-expression}1703 \rhs \lstinline$($ \nonterm{type-name} \lstinline$)$ \nonterm{cast-expression}1704 \end{syntax}1705 1706 \constraints1707 The \nonterm{type-name} in a \nonterm{cast-expression} shall not be \lstinline$type$,1708 \lstinline$dtype$, or \lstinline$ftype$.1709 1710 \semantics1711 1712 In a cast expression\index{cast expression} ``\lstinline$($\nonterm{type-name}\lstinline$)e$'', if1713 \nonterm{type-name} is the type of an interpretation of \lstinline$e$, then that interpretation is the1714 only interpretation of the cast expression; otherwise, \lstinline$e$ shall have some interpretation that1715 can be converted to \nonterm{type-name}, and the interpretation of the cast expression is the cast1716 of the interpretation that can be converted at the lowest cost. The cast expression's interpretation1717 is ambiguous\index{ambiguous interpretation} if more than one interpretation can be converted at the1718 lowest cost or if the selected interpretation is ambiguous.1719 1720 \begin{rationale}1721 Casts can be used to eliminate ambiguity in expressions by selecting interpretations of1722 subexpressions, and to specialize polymorphic functions and values.1723 \end{rationale}1724 1725 \subsection{Multiplicative operators}1726 \begin{syntax}1727 \lhs{multiplicative-expression}1728 \rhs \nonterm{cast-expression}1729 \rhs \nonterm{multiplicative-expression} \lstinline$*$ \nonterm{cast-expression}1730 \rhs \nonterm{multiplicative-expression} \lstinline$/$ \nonterm{cast-expression}1731 \rhs \nonterm{multiplicative-expression} \lstinline$%$ \nonterm{cast-expression}1732 \end{syntax}1733 1734 \rewriterules1735 \begin{lstlisting}1736 a * b @\rewrite@ ?*?( a, b )@\use{?*?}@1737 a / b @\rewrite@ ?/?( a, b )@\use{?/?}@1738 a % b @\rewrite@ ?%?( a, b )@\use{?%?}@1739 \end{lstlisting}1740 1741 \begin{lstlisting}1742 int?*?( int, int ),1743 ?/?( int, int ),1744 ?%?( int, int );1745 unsigned int?*?( unsigned int, unsigned int ),1746 ?/?( unsigned int, unsigned int ),1747 ?%?( unsigned int, unsigned int );1748 long int?*?( long int, long int ),1749 ?/?( long, long ),1750 ?%?( long, long );1751 long unsigned int?*?( long unsigned int, long unsigned int ),1752 ?/?( long unsigned int, long unsigned int ),1753 ?%?( long unsigned int, long unsigned int );1754 long long int?*?( long long int, long long int ),1755 ?/?( long long int, long long int ),1756 ?%?( long long int, long long int );1757 long long unsigned int ?*?( long long unsigned int, long long unsigned int ),1758 ?/?( long long unsigned int, long long unsigned int ),1759 ?%?( long long unsigned int, long long unsigned int );1760 float?*?( float, float ),1761 ?/?( float, float );1762 double?*?( double, double ),1763 ?/?( double, double );1764 long double?*?( long double, long double ),1765 ?/?( long double, long double );1766 _Complex float?*?( float, _Complex float ),1767 ?/?( float, _Complex float ),1768 ?*?( _Complex float, float ),1769 ?/?( _Complex float, float ),1770 ?*?( _Complex float, _Complex float ),1771 ?/?( _Complex float, _Complex float );1772 _Complex double?*?( double, _Complex double ),1773 ?/?( double, _Complex double ),1774 ?*?( _Complex double, double ),1775 ?/?( _Complex double, double ),1776 ?*?( _Complex double, _Complex double ),1777 ?/?( _Complex double, _Complex double );1778 _Complex long double?*?( long double, _Complex long double ),1779 ?/?( long double, _Complex long double ),1780 ?*?( _Complex long double, long double ),1781 ?/?( _Complex long double, long double ),1782 ?*?( _Complex long double, _Complex long double ),1783 ?/?( _Complex long double, _Complex long double );1784 \end{lstlisting}1785 For every extended integer type \lstinline$X$ with integer conversion rank \index{integer conversion1786 rank}greater than the rank of \lstinline$int$ there exist1787 % Don't use predefined: keep this out of prelude.cf.1788 \begin{lstlisting}1789 X ?*?( X ), ?/?( X ), ?%?( X );1790 \end{lstlisting}1791 1792 \begin{rationale}1793 {\c11} does not include conversions from the real types\index{real type} to complex1794 types\index{complex type} in the usual arithmetic conversions\index{usual arithmetic conversions}.1795 Instead it specifies conversion of the result of binary operations on arguments from mixed type1796 domains. \CFA's predefined operators match that pattern.1797 \end{rationale}1798 1799 \semantics1800 The interpretations of multiplicative expressions are the interpretations of the corresponding1801 function call.1802 1803 \examples1804 \begin{lstlisting}1805 int i;1806 long li;1807 void eat_double( double );@\use{eat_double}@1808 eat_double( li % i );1809 \end{lstlisting}1810 ``\lstinline$li % i$'' is rewritten as ``\lstinline$?%?(li, i )$''. The valid interpretations1811 of \lstinline$?%?(li, i )$, the cost\index{conversion cost} of converting their arguments, and1812 the cost of converting the result to \lstinline$double$ (assuming no extended integer types are1813 present ) are1814 \begin{center}1815 \begin{tabular}{lcc}1816 interpretation & argument cost & result cost \\1817 \hline1818 \lstinline$ ?%?( (int)li, i )$ & (unsafe) & 6 \\1819 \lstinline$ ?%?( (unsigned)li,(unsigned)i )$ & (unsafe) & 5 \\1820 \lstinline$ ?%?(li,(long)i )$ & 1 & 4 \\1821 \lstinline$ ?%?( (long unsigned)li,(long unsigned)i )$ & 3 & 3 \\1822 \lstinline$ ?%?( (long long)li,(long long)i )$ & 5 & 2 \\1823 \lstinline$ ?%?( (long long unsigned)li, (long long unsigned)i )$ & 7 & 1 \\1824 \end{tabular}1825 \end{center}1826 The best interpretation of \lstinline$eat_double( li, i )$ is1827 \lstinline$eat_double( (double)?%?(li, (long)i ))$, which has no unsafe conversions and the1828 lowest total cost.1829 1830 \begin{rationale}1831 {\c11} defines most arithmetic operations to apply an integer promotion\index{integer promotions} to1832 any argument that belongs to a type that has an integer conversion rank\index{integer conversion1833 rank} less than that of \lstinline$int$.If \lstinline$s$ is a \lstinline$short int$,1834 ``\lstinline$s *s$'' does not have type \lstinline$short int$; it is treated as1835 ``\lstinline$( (int)s ) * ( (int)s )$'', and has type \lstinline$int$. \CFA matches that pattern;1836 it does not predefine ``\lstinline$short ?*?( short, short )$''.1837 1838 These ``missing'' operators limit polymorphism. Consider1839 \begin{lstlisting}1840 forall( type T | T ?*?( T, T ) ) T square( T );1841 short s;1842 square( s );1843 \end{lstlisting}1844 Since \CFA does not define a multiplication operator for \lstinline$short int$,1845 \lstinline$square( s )$ is treated as \lstinline$square( (int)s )$, and the result has type1846 \lstinline$int$. This is mildly surprising, but it follows the {\c11} operator pattern.1847 1848 A more troubling example is1849 \begin{lstlisting}1850 forall( type T | ?*?( T, T ) ) T product( T[], int n );1851 short sa[5];1852 product( sa, 5);1853 \end{lstlisting}1854 This has no valid interpretations, because \CFA has no conversion from ``array of1855 \lstinline$short int$'' to ``array of \lstinline$int$''. The alternatives in such situations1856 include1857 \begin{itemize}1858 \item1859 Defining monomorphic overloadings of \lstinline$product$ for \lstinline$short$ and the other1860 ``small'' types.1861 \item1862 Defining ``\lstinline$short ?*?( short, short )$'' within the scope containing the call to1863 \lstinline$product$.1864 \item1865 Defining \lstinline$product$ to take as an argument a conversion function from the ``small'' type to1866 the operator's argument type.1867 \end{itemize}1868 \end{rationale}1869 1870 1871 \subsection{Additive operators}1872 1873 \begin{syntax}1874 \lhs{additive-expression}1875 \rhs \nonterm{multiplicative-expression}1876 \rhs \nonterm{additive-expression} \lstinline$+$ \nonterm{multiplicative-expression}1877 \rhs \nonterm{additive-expression} \lstinline$-$ \nonterm{multiplicative-expression}1878 \end{syntax}1879 1880 \rewriterules1881 \begin{lstlisting}1882 a + b @\rewrite@ ?+?( a, b )@\use{?+?}@1883 a - b @\rewrite@ ?-?( a, b )@\use{?-?}@1884 \end{lstlisting}1885 1886 \begin{lstlisting}1887 int?+?( int, int ),1888 ?-?( int, int );1889 unsigned int?+?( unsigned int, unsigned int ),1890 ?-?( unsigned int, unsigned int );1891 long int?+?( long int, long int ),1892 ?-?( long int, long int );1893 long unsigned int?+?( long unsigned int, long unsigned int ),1894 ?-?( long unsigned int, long unsigned int );1895 long long int?+?( long long int, long long int ),1896 ?-?( long long int, long long int );1897 long long unsigned int ?+?( long long unsigned int, long long unsigned int ),1898 ?-?( long long unsigned int, long long unsigned int );1899 float?+?( float, float ),1900 ?-?( float, float );1901 double?+?( double, double ),1902 ?-?( double, double );1903 long double?+?( long double, long double ),1904 ?-?( long double, long double );1905 _Complex float?+?( _Complex float, float ),1906 ?-?( _Complex float, float ),1907 ?+?( float, _Complex float ),1908 ?-?( float, _Complex float ),1909 ?+?( _Complex float, _Complex float ),1910 ?-?( _Complex float, _Complex float );1911 _Complex double?+?( _Complex double, double ),1912 ?-?( _Complex double, double ),1913 ?+?( double, _Complex double ),1914 ?-?( double, _Complex double ),1915 ?+?( _Complex double, _Complex double ),1916 ?-?( _Complex double, _Complex double );1917 _Complex long double?+?( _Complex long double, long double ),1918 ?-?( _Complex long double, long double ),1919 ?+?( long double, _Complex long double ),1920 ?-?( long double, _Complex long double ),1921 ?+?( _Complex long double, _Complex long double ),1922 ?-?( _Complex long double, _Complex long double );1923 1924 forall( type T ) T1925 * ?+?( T *, ptrdiff_t ),1926 * ?+?( ptrdiff_t, T * ),1927 * ?-?( T *, ptrdiff_t );1928 1929 forall( type T ) _Atomic T1930 * ?+?( _Atomic T *, ptrdiff_t ),1931 * ?+?( ptrdiff_t, _Atomic T * ),1932 * ?-?( _Atomic T *, ptrdiff_t );1933 1934 forall( type T ) const T1935 * ?+?( const T *, ptrdiff_t ),1936 * ?+?( ptrdiff_t, const T * ),1937 * ?-?( const T *, ptrdiff_t );1938 1939 forall( type T ) restrict T1940 * ?+?( restrict T *, ptrdiff_t ),1941 * ?+?( ptrdiff_t, restrict T * ),1942 * ?-?( restrict T *, ptrdiff_t );1943 1944 forall( type T ) volatile T1945 * ?+?( volatile T *, ptrdiff_t ),1946 * ?+?( ptrdiff_t, volatile T * ),1947 * ?-?( volatile T *, ptrdiff_t );1948 1949 forall( type T ) _Atomic const T1950 * ?+?( _Atomic const T *, ptrdiff_t ),1951 * ?+?( ptrdiff_t, _Atomic const T * ),1952 * ?-?( _Atomic const T *, ptrdiff_t );1953 1954 forall( type T ) _Atomic restrict T1955 * ?+?( _Atomic restrict T *, ptrdiff_t ),1956 * ?+?( ptrdiff_t, _Atomic restrict T * ),1957 * ?-?( _Atomic restrict T *, ptrdiff_t );1958 1959 forall( type T ) _Atomic volatile T1960 * ?+?( _Atomic volatile T *, ptrdiff_t ),1961 * ?+?( ptrdiff_t, _Atomic volatile T * ),1962 * ?-?( _Atomic volatile T *, ptrdiff_t );1963 1964 forall( type T ) const restrict T1965 * ?+?( const restrict T *, ptrdiff_t ),1966 * ?+?( ptrdiff_t, const restrict T * ),1967 * ?-?( const restrict T *, ptrdiff_t );1968 1969 forall( type T ) const volatile T1970 * ?+?( const volatile T *, ptrdiff_t ),1971 * ?+?( ptrdiff_t, const volatile T * ),1972 * ?-?( const volatile T *, ptrdiff_t );1973 1974 forall( type T ) restrict volatile T1975 * ?+?( restrict volatile T *, ptrdiff_t ),1976 * ?+?( ptrdiff_t, restrict volatile T * ),1977 * ?-?( restrict volatile T *, ptrdiff_t );1978 1979 forall( type T ) _Atomic const restrict T1980 * ?+?( _Atomic const restrict T *, ptrdiff_t ),1981 * ?+?( ptrdiff_t, _Atomic const restrict T * ),1982 * ?-?( _Atomic const restrict T *, ptrdiff_t );1983 1984 forall( type T ) ptrdiff_t1985 * ?-?( const restrict volatile T *, const restrict volatile T * ),1986 * ?-?( _Atomic const restrict volatile T *, _Atomic const restrict volatile T * );1987 \end{lstlisting}1988 For every extended integer type \lstinline$X$ with integer conversion rank1989 \index{integer conversion rank}greater than the rank of \lstinline$int$ there1990 exist1991 % Don't use predefined: keep this out of prelude.cf.1992 \begin{lstlisting}1993 X ?+?( X ), ?-?( X );1994 \end{lstlisting}1995 1996 \semantics1997 The interpretations of additive expressions are the interpretations of the corresponding function1998 calls.1999 2000 \begin{rationale}2001 \lstinline$ptrdiff_t$ is an implementation-defined identifier defined in \lstinline$<stddef.h>$ that2002 is synonymous with a signed integral type that is large enough to hold the difference between two2003 pointers. It seems reasonable to use it for pointer addition as well. (This is technically a2004 difference between \CFA and C, which only specifies that pointer addition uses an \emph{integral}2005 argument.) Hence it is also used for subscripting, which is defined in terms of pointer addition.2006 The {\c11} standard uses \lstinline$size_t$ in several cases where a library function takes an2007 argument that is used as a subscript, but \lstinline$size_t$ is unsuitable here because it is an2008 unsigned type.2009 \end{rationale}2010 2011 2012 \subsection{Bitwise shift operators}2013 2014 \begin{syntax}2015 \lhs{shift-expression}2016 \rhs \nonterm{additive-expression}2017 \rhs \nonterm{shift-expression} \lstinline$<<$ \nonterm{additive-expression}2018 \rhs \nonterm{shift-expression} \lstinline$>>$ \nonterm{additive-expression}2019 \end{syntax}2020 2021 \rewriterules \use{?>>?}%use{?<<?}2022 \begin{lstlisting}2023 a << b @\rewrite@ ?<<?( a, b )2024 a >> b @\rewrite@ ?>>?( a, b )2025 \end{lstlisting}2026 2027 \begin{lstlisting}2028 int ?<<?( int, int ),2029 ?>>?( int, int );2030 unsigned int ?<<?( unsigned int, int ),2031 ?>>?( unsigned int, int );2032 long int ?<<?( long int, int ),2033 ?>>?( long int, int );2034 long unsigned int ?<<?( long unsigned int, int ),2035 ?>>?( long unsigned int, int );2036 long long int ?<<?( long long int, int ),2037 ?>>?( long long int, int );2038 long long unsigned int ?<<?( long long unsigned int, int ),2039 ?>>?( long long unsigned int, int);2040 \end{lstlisting}2041 For every extended integer type \lstinline$X$ with integer conversion rank \index{integer conversion2042 rank}greater than the rank of \lstinline$int$ there exist2043 % Don't use predefined: keep this out of prelude.cf.2044 \begin{lstlisting}2045 X ?<<?( X, int ), ?>>?( X, int );2046 \end{lstlisting}2047 2048 \begin{rationale}2049 The bitwise shift operators break the usual pattern: they do not convert both operands to a common2050 type. The right operand only undergoes integer promotion\index{integer promotion}.2051 \end{rationale}2052 2053 \semantics2054 The interpretations of a bitwise shift expression are the interpretations of the corresponding2055 function calls.2056 2057 2058 \subsection{Relational operators}2059 2060 \begin{syntax}2061 \lhs{relational-expression}2062 \rhs \nonterm{shift-expression}2063 \rhs \nonterm{relational-expression} \lstinline$< $ \nonterm{shift-expression}2064 \rhs \nonterm{relational-expression} \lstinline$> $ \nonterm{shift-expression}2065 \rhs \nonterm{relational-expression} \lstinline$<=$ \nonterm{shift-expression}2066 \rhs \nonterm{relational-expression} \lstinline$>=$ \nonterm{shift-expression}2067 \end{syntax}2068 2069 \rewriterules\use{?>?}\use{?>=?}%use{?<?}%use{?<=?}2070 \begin{lstlisting}2071 a < b @\rewrite@ ?<?( a, b )2072 a > b @\rewrite@ ?>?( a, b )2073 a <= b @\rewrite@ ?<=?( a, b )2074 a >= b @\rewrite@ ?>=?( a, b )2075 \end{lstlisting}2076 2077 \begin{lstlisting}2078 int ?<?( int, int ),2079 ?<=?( int, int ),2080 ?>?( int, int ),2081 ?>=?( int, int );2082 int ?<?( unsigned int, unsigned int ),2083 ?<=?( unsigned int, unsigned int ),2084 ?>?( unsigned int, unsigned int ),2085 ?>=?( unsigned int, unsigned int );2086 int ?<?( long int, long int ),2087 ?<=?( long int, long int ),2088 ?>?( long int, long int ),2089 ?>=?( long int, long int );2090 int ?<?( long unsigned int, long unsigned ),2091 ?<=?( long unsigned int, long unsigned ),2092 ?>?( long unsigned int, long unsigned ),2093 ?>=?( long unsigned int, long unsigned );2094 int ?<?( long long int, long long int ),2095 ?<=?( long long int, long long int ),2096 ?>?( long long int, long long int ),2097 ?>=?( long long int, long long int );2098 int ?<?( long long unsigned int, long long unsigned ),2099 ?<=?( long long unsigned int, long long unsigned ),2100 ?>?( long long unsigned int, long long unsigned ),2101 ?>=?( long long unsigned int, long long unsigned );2102 int ?<?( float, float ),2103 ?<=?( float, float ),2104 ?>?( float, float ),2105 ?>=?( float, float );2106 int ?<?( double, double ),2107 ?<=?( double, double ),2108 ?>?( double, double ),2109 ?>=?( double, double );2110 int ?<?( long double, long double ),2111 ?<=?( long double, long double ),2112 ?>?( long double, long double ),2113 ?>=?( long double, long double );2114 2115 forall( dtype DT ) int2116 ?<?( const restrict volatile DT *, const restrict volatile DT * ),2117 ?<?( _Atomic const restrict volatile DT *, _Atomic const restrict volatile DT * ),2118 ?<=?( const restrict volatile DT *, const restrict volatile DT * ),2119 ?<=?( _Atomic const restrict volatile DT *, _Atomic const restrict volatile DT * ),2120 ?>?( const restrict volatile DT *, const restrict volatile DT * ),2121 ?>?( _Atomic const restrict volatile DT *, _Atomic const restrict volatile DT * ),2122 ?>=?( const restrict volatile DT *, const restrict volatile DT * ),2123 ?>=?( _Atomic const restrict volatile DT *, _Atomic const restrict volatile DT * );2124 \end{lstlisting}2125 For every extended integer type \lstinline$X$ with integer conversion rank \index{integer conversion2126 rank}greater than the rank of \lstinline$int$ there exist2127 % Don't use predefined: keep this out of prelude.cf.2128 \begin{lstlisting}2129 int ?<?( X, X ),2130 ?<=?( X, X ),2131 ?<?( X, X ),2132 ?>=?( X, X );2133 \end{lstlisting}2134 2135 \semantics2136 The interpretations of a relational expression are the interpretations of the corresponding function2137 call.2138 2139 2140 \subsection{Equality operators}2141 2142 \begin{syntax}2143 \lhs{equality-expression}2144 \rhs \nonterm{relational-expression}2145 \rhs \nonterm{equality-expression} \lstinline$==$ \nonterm{relational-expression}2146 \rhs \nonterm{equality-expression} \lstinline$!=$ \nonterm{relational-expression}2147 \end{syntax}2148 2149 \rewriterules2150 \begin{lstlisting}2151 a == b @\rewrite@ ?==?( a, b )@\use{?==?}@2152 a != b @\rewrite@ ?!=?( a, b )@\use{?"!=?}@2153 \end{lstlisting}2154 2155 \begin{lstlisting}2156 int ?==?( int, int ),2157 ?!=?( int, int ),2158 ?==?( unsigned int, unsigned int ),2159 ?!=?( unsigned int, unsigned int ),2160 ?==?( long int, long int ),2161 ?!=?( long int, long int ),2162 ?==?( long unsigned int, long unsigned int ),2163 ?!=?( long unsigned int, long unsigned int ),2164 ?==?( long long int, long long int ),2165 ?!=?( long long int, long long int ),2166 ?==?( long long unsigned int, long long unsigned int ),2167 ?!=?( long long unsigned int, long long unsigned int ),2168 ?==?( float, float ),2169 ?!=?( float, float ),2170 ?==?( _Complex float, float ),2171 ?!=?( _Complex float, float ),2172 ?==?( float, _Complex float ),2173 ?!=?( float, _Complex float ),2174 ?==?( _Complex float, _Complex float ),2175 ?!=?( _Complex float, _Complex float ),2176 ?==?( double, double ),2177 ?!=?( double, double ),2178 ?==?( _Complex double, double ),2179 ?!=?( _Complex double, double ),2180 ?==?( double, _Complex double ),2181 ?!=?( double, _Complex double ),2182 ?==?( _Complex double, _Complex double ),2183 ?!=?( _Complex double, _Complex double ),2184 ?==?( long double, long double ),2185 ?!=?( long double, long double ),2186 ?==?( _Complex long double, long double ),2187 ?!=?( _Complex long double, long double ),2188 ?==?( long double, _Complex long double ),2189 ?!=?( long double, _Complex long double ),2190 ?==?( _Complex long double, _Complex long double ),2191 ?!=?( _Complex long double, _Complex long double );2192 2193 forall( dtype DT ) int2194 ?==?( const restrict volatile DT *, const restrict volatile DT * ),2195 ?!=?( const restrict volatile DT *, const restrict volatile DT * ),2196 ?==?( const restrict volatile DT *, const restrict volatile void * ),2197 ?!=?( const restrict volatile DT *, const restrict volatile void * ),2198 ?==?( const restrict volatile void *, const restrict volatile DT * ),2199 ?!=?( const restrict volatile void *, const restrict volatile DT * ),2200 ?==?( const restrict volatile DT *, forall( dtype DT2) const DT2 * ),2201 ?!=?( const restrict volatile DT *, forall( dtype DT2) const DT2 * ),2202 ?==?( forall( dtype DT2) const DT2*, const restrict volatile DT * ),2203 ?!=?( forall( dtype DT2) const DT2*, const restrict volatile DT * ),2204 ?==?( forall( dtype DT2) const DT2*, forall( dtype DT3) const DT3 * ),2205 ?!=?( forall( dtype DT2) const DT2*, forall( dtype DT3) const DT3 * ),2206 2207 ?==?( _Atomic const restrict volatile DT *, _Atomic const restrict volatile DT * ),2208 ?!=?( _Atomic const restrict volatile DT *, _Atomic const restrict volatile DT * ),2209 ?==?( _Atomic const restrict volatile DT *, const restrict volatile void * ),2210 ?!=?( _Atomic const restrict volatile DT *, const restrict volatile void * ),2211 ?==?( const restrict volatile void *, _Atomic const restrict volatile DT * ),2212 ?!=?( const restrict volatile void *, _Atomic const restrict volatile DT * ),2213 ?==?( _Atomic const restrict volatile DT *, forall( dtype DT2) const DT2 * ),2214 ?!=?( _Atomic const restrict volatile DT *, forall( dtype DT2) const DT2 * ),2215 ?==?( forall( dtype DT2) const DT2*, _Atomic const restrict volatile DT * ),2216 ?!=?( forall( dtype DT2) const DT2*, _Atomic const restrict volatile DT * );2217 2218 forall( ftype FT ) int2219 ?==?( FT *, FT * ),2220 ?!=?( FT *, FT * ),2221 ?==?( FT *, forall( ftype FT2) FT2 * ),2222 ?!=?( FT *, forall( ftype FT2) FT2 * ),2223 ?==?( forall( ftype FT2) FT2*, FT * ),2224 ?!=?( forall( ftype FT2) FT2*, FT * ),2225 ?==?( forall( ftype FT2) FT2*, forall( ftype FT3) FT3 * ),2226 ?!=?( forall( ftype FT2) FT2*, forall( ftype FT3) FT3 * );2227 \end{lstlisting}2228 For every extended integer type \lstinline$X$ with integer conversion rank \index{integer conversion2229 rank}greater than the rank of \lstinline$int$ there exist2230 % Don't use predefined: keep this out of prelude.cf.2231 \begin{lstlisting}2232 int ?==?( X, X ),2233 ?!=?( X, X );2234 \end{lstlisting}2235 2236 \begin{rationale}2237 The polymorphic equality operations come in three styles: comparisons between pointers of compatible2238 types, between pointers to \lstinline$void$ and pointers to object types or incomplete types, and2239 between the null pointer constant\index{null pointer} and pointers to any type. In the last case, a2240 special constraint rule for null pointer constant operands has been replaced by a consequence of the2241 \CFA type system.2242 \end{rationale}2243 2244 \semantics2245 The interpretations of an equality expression are the interpretations of the corresponding function2246 call.2247 2248 \begin{sloppypar}2249 The result of an equality comparison between two pointers to predefined functions or predefined2250 values is implementation-defined.2251 \end{sloppypar}2252 \begin{rationale}2253 The implementation-defined status of equality comparisons allows implementations to use one library2254 routine to implement many predefined functions. These optimization are particularly important when2255 the predefined functions are polymorphic, as is the case for most pointer operations2256 \end{rationale}2257 2258 2259 \subsection{Bitwise AND operator}2260 2261 \begin{syntax}2262 \lhs{AND-expression}2263 \rhs \nonterm{equality-expression}2264 \rhs \nonterm{AND-expression} \lstinline$&$ \nonterm{equality-expression}2265 \end{syntax}2266 2267 \rewriterules2268 \begin{lstlisting}2269 a & b @\rewrite@ ?&?( a, b )@\use{?&?}@2270 \end{lstlisting}2271 2272 \begin{lstlisting}2273 int ?&?( int, int );2274 unsigned int ?&?( unsigned int, unsigned int );2275 long int ?&?( long int, long int );2276 long unsigned int ?&?( long unsigned int, long unsigned int );2277 long long int ?&?( long long int, long long int );2278 long long unsigned int ?&?( long long unsigned int, long long unsigned int );2279 \end{lstlisting}2280 For every extended integer type \lstinline$X$ with integer conversion rank \index{integer conversion2281 rank}greater than the rank of \lstinline$int$ there exist2282 % Don't use predefined: keep this out of prelude.cf.2283 \begin{lstlisting}2284 int ?&?( X, X );2285 \end{lstlisting}2286 2287 \semantics2288 The interpretations of a bitwise AND expression are the interpretations of the corresponding2289 function call.2290 2291 2292 \subsection{Bitwise exclusive OR operator}2293 2294 \begin{syntax}2295 \lhs{exclusive-OR-expression}2296 \rhs \nonterm{AND-expression}2297 \rhs \nonterm{exclusive-OR-expression} \lstinline$^$ \nonterm{AND-expression}2298 \end{syntax}2299 2300 \rewriterules2301 \begin{lstlisting}2302 a ^ b @\rewrite@ ?^?( a, b )@\use{?^?}@2303 \end{lstlisting}2304 2305 \begin{lstlisting}2306 int ?^?( int, int );2307 unsigned int ?^?( unsigned int, unsigned int );2308 long int ?^?( long int, long int );2309 long unsigned int ?^?( long unsigned int, long unsigned int );2310 long long int ?^?( long long int, long long int );2311 long long unsigned int ?^?( long long unsigned int, long long unsigned int );2312 \end{lstlisting}2313 For every extended integer type \lstinline$X$ with integer conversion rank \index{integer conversion2314 rank}greater than the rank of \lstinline$int$ there exist2315 % Don't use predefined: keep this out of prelude.cf.2316 \begin{lstlisting}2317 int ?^?( X, X );2318 \end{lstlisting}2319 2320 \semantics2321 The interpretations of a bitwise exclusive OR expression are the interpretations of the2322 corresponding function call.2323 2324 2325 \subsection{Bitwise inclusive OR operator}2326 2327 \begin{syntax}2328 \lhs{inclusive-OR-expression}2329 \rhs \nonterm{exclusive-OR-expression}2330 \rhs \nonterm{inclusive-OR-expression} \lstinline$|$ \nonterm{exclusive-OR-expression}2331 \end{syntax}2332 2333 \rewriterules\use{?"|?}2334 \begin{lstlisting}2335 a | b @\rewrite@ ?|?( a, b )2336 \end{lstlisting}2337 2338 \begin{lstlisting}2339 int ?|?( int, int );2340 unsigned int ?|?( unsigned int, unsigned int );2341 long int ?|?( long int, long int );2342 long unsigned int ?|?( long unsigned int, long unsigned int );2343 long long int ?|?( long long int, long long int );2344 long long unsigned int ?|?( long long unsigned int, long long unsigned int );2345 \end{lstlisting}2346 For every extended integer type \lstinline$X$ with integer conversion rank \index{integer conversion2347 rank}greater than the rank of \lstinline$int$ there exist2348 % Don't use predefined: keep this out of prelude.cf.2349 \begin{lstlisting}2350 int ?|?( X, X );2351 \end{lstlisting}2352 2353 \semantics2354 The interpretations of a bitwise inclusive OR expression are the interpretations of the2355 corresponding function call.2356 2357 2358 \subsection{Logical AND operator}2359 2360 \begin{syntax}2361 \lhs{logical-AND-expression}2362 \rhs \nonterm{inclusive-OR-expression}2363 \rhs \nonterm{logical-AND-expression} \lstinline$&&$ \nonterm{inclusive-OR-expression}2364 \end{syntax}2365 2366 \semantics The operands of the expression ``\lstinline$a && b$'' are treated as2367 ``\lstinline$(int)((a)!=0)$'' and ``\lstinline$(int)((b)!=0)$'', which shall both be2368 unambiguous. The expression has only one interpretation, which is of type \lstinline$int$.2369 \begin{rationale}2370 When the operands of a logical expression are values of built-in types, and ``\lstinline$!=$'' has2371 not been redefined for those types, the compiler can optimize away the function calls.2372 2373 A common C idiom omits comparisons to \lstinline$0$ in the controlling expressions of loops and2374 \lstinline$if$ statements. For instance, the loop below iterates as long as \lstinline$rp$ points2375 at a \lstinline$Rational$ value that is non-zero.2376 2377 \begin{lstlisting}2378 extern type Rational;@\use{Rational}@2379 extern const Rational 0;@\use{0}@2380 extern int ?!=?( Rational, Rational );2381 Rational *rp;2382 2383 while ( rp && *rp ) { ... }2384 \end{lstlisting}2385 The logical expression calls the \lstinline$Rational$ inequality operator, passing2386 it \lstinline$*rp$ and the \lstinline$Rational 0$, and getting a 1 or 0 as a result. In2387 contrast, {\CC} would apply a programmer-defined \lstinline$Rational$-to-\lstinline$int$2388 conversion to \lstinline$*rp$ in the equivalent situation. The conversion to \lstinline$int$ would2389 produce a general integer value, which is unfortunate, and possibly dangerous if the conversion was2390 not written with this situation in mind.2391 \end{rationale}2392 2393 2394 \subsection{Logical OR operator}2395 2396 \begin{syntax}2397 \lhs{logical-OR-expression}2398 \rhs \nonterm{logical-AND-expression}2399 \rhs \nonterm{logical-OR-expression} \lstinline$||$ \nonterm{logical-AND-expression}2400 \end{syntax}2401 2402 \semantics2403 2404 The operands of the expression ``\lstinline$a || b$'' are treated as ``\lstinline$(int)((a)!=0)$''2405 and ``\lstinline$(int)((b})!=0)$'', which shall both be unambiguous. The expression has only one2406 interpretation, which is of type \lstinline$int$.2407 2408 2409 \subsection{Conditional operator}2410 2411 \begin{syntax}2412 \lhs{conditional-expression}2413 \rhs \nonterm{logical-OR-expression}2414 \rhs \nonterm{logical-OR-expression} \lstinline$?$ \nonterm{expression}2415 \lstinline$:$ \nonterm{conditional-expression}2416 \end{syntax}2417 2418 \semantics2419 In the conditional expression\use{?:} ``\lstinline$a?b:c$'', if the second and2420 third operands both have an interpretation with \lstinline$void$ type, then the expression has an2421 interpretation with type \lstinline$void$, equivalent to2422 \begin{lstlisting}2423 ( int)(( a)!=0) ? ( void)( b) : ( void)( c)2424 \end{lstlisting}2425 2426 If the second and third operands both have interpretations with non-\lstinline$void$ types, the2427 expression is treated as if it were the call ``\lstinline$cond((a)!=0, b, c)$'',2428 with \lstinline$cond$ declared as2429 \begin{lstlisting}2430 forall( type T ) T cond( int, T, T );2431 2432 forall( dtype D ) void2433 * cond( int, D *, void * ),2434 * cond( int, void *, D * );2435 2436 forall( dtype D ) _atomic void2437 * cond( int, _Atomic D *, _Atomic void * ),2438 * cond( int, _Atomic void *, _Atomic D * );2439 2440 forall( dtype D ) const void2441 * cond( int, const D *, const void * ),2442 * cond( int, const void *, const D * );2443 2444 forall( dtype D ) restrict void2445 * cond( int, restrict D *, restrict void * ),2446 * cond( int, restrict void *, restrict D * );2447 2448 forall( dtype D ) volatile void2449 * cond( int, volatile D *, volatile void * ),2450 * cond( int, volatile void *, volatile D * );2451 2452 forall( dtype D ) _Atomic const void2453 * cond( int, _Atomic const D *, _Atomic const void * ),2454 * cond( int, _Atomic const void *, _Atomic const D * );2455 2456 forall( dtype D ) _Atomic restrict void2457 * cond( int, _Atomic restrict D *, _Atomic restrict void * ),2458 * cond( int, _Atomic restrict void *, _Atomic restrict D * );2459 2460 forall( dtype D ) _Atomic volatile void2461 * cond( int, _Atomic volatile D *, _Atomic volatile void * ),2462 * cond( int, _Atomic volatile void *, _Atomic volatile D * );2463 2464 forall( dtype D ) const restrict void2465 * cond( int, const restrict D *, const restrict void * ),2466 * cond( int, const restrict void *, const restrict D * );2467 2468 forall( dtype D ) const volatile void2469 * cond( int, const volatile D *, const volatile void * ),2470 * cond( int, const volatile void *, const volatile D * );2471 2472 forall( dtype D ) restrict volatile void2473 * cond( int, restrict volatile D *, restrict volatile void * ),2474 * cond( int, restrict volatile void *, restrict volatile D * );2475 2476 forall( dtype D ) _Atomic const restrict void2477 * cond( int, _Atomic const restrict D *, _Atomic const restrict void * ),2478 * cond( int, _Atomic const restrict void *, _Atomic const restrict D * );2479 2480 forall( dtype D ) _Atomic const volatile void2481 * cond( int, _Atomic const volatile D *, _Atomic const volatile void * ),2482 * cond( int, _Atomic const volatile void *, _Atomic const volatile D * );2483 2484 forall( dtype D ) _Atomic restrict volatile void2485 * cond( int, _Atomic restrict volatile D *,2486 _Atomic restrict volatile void * ),2487 * cond( int, _Atomic restrict volatile void *,2488 _Atomic restrict volatile D * );2489 2490 forall( dtype D ) const restrict volatile void2491 * cond( int, const restrict volatile D *,2492 const restrict volatile void * ),2493 * cond( int, const restrict volatile void *,2494 const restrict volatile D * );2495 2496 forall( dtype D ) _Atomic const restrict volatile void2497 * cond( int, _Atomic const restrict volatile D *,2498 _Atomic const restrict volatile void * ),2499 * cond( int, _Atomic const restrict volatile void *,2500 _Atomic const restrict volatile D * );2501 \end{lstlisting}2502 2503 \begin{rationale}2504 The object of the above is to apply the usual arithmetic conversions\index{usual arithmetic2505 conversions} when the second and third operands have arithmetic type, and to combine the2506 qualifiers of the second and third operands if they are pointers.2507 \end{rationale}2508 2509 \examples2510 \begin{lstlisting}2511 #include <stdlib.h>2512 int i;2513 long l;2514 rand() ? i : l;2515 \end{lstlisting}2516 The best interpretation infers the expression's type to be \lstinline$long$ and applies the safe2517 \lstinline$int$-to-\lstinline$long$ conversion to \lstinline$i$.2518 2519 \begin{lstlisting}2520 const int *cip;2521 volatile int *vip;2522 rand() ? cip : vip;2523 \end{lstlisting}2524 The expression has type \lstinline$const volatile int *$, with safe conversions applied to the second2525 and third operands to add \lstinline$volatile$ and \lstinline$const$ qualifiers, respectively.2526 2527 \begin{lstlisting}2528 rand() ? cip : 0;2529 \end{lstlisting}2530 The expression has type \lstinline$const int *$, with a specialization conversion applied to2531 \lstinline$0$.2532 2533 2534 \subsection{Assignment operators}2535 2536 \begin{syntax}2537 \lhs{assignment-expression}2538 \rhs \nonterm{conditional-expression}2539 \rhs \nonterm{unary-expression} \nonterm{assignment-operator}2540 \nonterm{assignment-expression}2541 \lhs{assignment-operator} one of2542 \rhs \lstinline$=$\ \ \lstinline$*=$\ \ \lstinline$/=$\ \ \lstinline$%=$\ \ \lstinline$+=$\ \ \lstinline$-=$\ \2543 \lstinline$<<=$\ \ \lstinline$>>=$\ \ \lstinline$&=$\ \ \lstinline$^=$\ \ \lstinline$|=$2544 \end{syntax}2545 2546 \rewriterules2547 Let ``\(\leftarrow\)'' be any of the assignment operators. Then2548 \use{?=?}\use{?*=?}\use{?/=?}\use{?%=?}\use{?+=?}\use{?-=?}2549 \use{?>>=?}\use{?&=?}\use{?^=?}\use{?"|=?}%use{?<<=?}2550 \begin{lstlisting}2551 a @$\leftarrow$@ b @\rewrite@ ?@$\leftarrow$@?( &( a ), b )2552 \end{lstlisting}2553 2554 \semantics2555 Each interpretation of the left operand of an assignment expression is considered separately. For2556 each interpretation that is a bit-field or is declared with the \lstinline$register$ storage class2557 specifier, the expression has one valid interpretation, with the type of the left operand. The2558 right operand is cast to that type, and the assignment expression is ambiguous if either operand is.2559 For the remaining interpretations, the expression is rewritten, and the interpretations of the2560 assignment expression are the interpretations of the corresponding function call. Finally, all2561 interpretations of the expression produced for the different interpretations of the left operand are2562 combined to produce the interpretations of the expression as a whole; where interpretations have2563 compatible result types, the best interpretations are selected in the manner described for function2564 call expressions.2565 2566 2567 \subsubsection{Simple assignment}2568 2569 \begin{lstlisting}2570 _Bool2571 ?=?( volatile _Bool *, _Bool ),2572 ?=?( volatile _Bool *, forall( dtype D ) D * ),2573 ?=?( volatile _Bool *, forall( ftype F ) F * ),2574 ?=?( _Atomic volatile _Bool *, _Bool ),2575 ?=?( _Atomic volatile _Bool *, forall( dtype D ) D * ),2576 ?=?( _Atomic volatile _Bool *, forall( ftype F ) F * );2577 char2578 ?=?( volatile char *, char ),2579 ?=?( _Atomic volatile char *, char );2580 unsigned char2581 ?=?( volatile unsigned char *, unsigned char ),2582 ?=?( _Atomic volatile unsigned char *, unsigned char );2583 signed char2584 ?=?( volatile signed char *, signed char ),2585 ?=?( _Atomic volatile signed char *, signed char );2586 short int2587 ?=?( volatile short int *, short int ),2588 ?=?( _Atomic volatile short int *, short int );2589 unsigned short2590 ?=?( volatile unsigned int *, unsigned int ),2591 ?=?( _Atomic volatile unsigned int *, unsigned int );2592 int2593 ?=?( volatile int *, int ),2594 ?=?( _Atomic volatile int *, int );2595 unsigned int2596 ?=?( volatile unsigned int *, unsigned int ),2597 ?=?( _Atomic volatile unsigned int *, unsigned int );2598 long int2599 ?=?( volatile long int *, long int ),2600 ?=?( _Atomic volatile long int *, long int );2601 unsigned long int2602 ?=?( volatile unsigned long int *, unsigned long int ),2603 ?=?( _Atomic volatile unsigned long int *, unsigned long int );2604 long long int2605 ?=?( volatile long long int *, long long int ),2606 ?=?( _Atomic volatile long long int *, long long int );2607 unsigned long long int2608 ?=?( volatile unsigned long long int *, unsigned long long int ),2609 ?=?( _Atomic volatile unsigned long long int *, unsigned long long int );2610 float2611 ?=?( volatile float *, float ),2612 ?=?( _Atomic volatile float *, float );2613 double2614 ?=?( volatile double *, double ),2615 ?=?( _Atomic volatile double *, double );2616 long double2617 ?=?( volatile long double *, long double ),2618 ?=?( _Atomic volatile long double *, long double );2619 _Complex float2620 ?=?( volatile float *, float ),2621 ?=?( _Atomic volatile float *, float );2622 _Complex double2623 ?=?( volatile double *, double ),2624 ?=?( _Atomic volatile double *, double );2625 _Complex long double2626 ?=?( volatile _Complex long double *, _Complex long double ),2627 ?=?( _Atomic volatile _Complex long double *, _Atomic _Complex long double );2628 2629 forall( ftype FT ) FT2630 * ?=?( FT * volatile *, FT * ),2631 * ?=?( FT * volatile *, forall( ftype F ) F * );2632 2633 forall( ftype FT ) FT const2634 * ?=?( FT const * volatile *, FT const * ),2635 * ?=?( FT const * volatile *, forall( ftype F ) F * );2636 2637 forall( ftype FT ) FT volatile2638 * ?=?( FT volatile * volatile *, FT * ),2639 * ?=?( FT volatile * volatile *, forall( ftype F ) F * );2640 2641 forall( ftype FT ) FT const2642 * ?=?( FT const volatile * volatile *, FT const * ),2643 * ?=?( FT const volatile * volatile *, forall( ftype F ) F * );2644 2645 forall( dtype DT ) DT2646 * ?=?( DT * restrict volatile *, DT * ),2647 * ?=?( DT * restrict volatile *, void * ),2648 * ?=?( DT * restrict volatile *, forall( dtype D ) D * ),2649 * ?=?( DT * _Atomic restrict volatile *, DT * ),2650 * ?=?( DT * _Atomic restrict volatile *, void * ),2651 * ?=?( DT * _Atomic restrict volatile *, forall( dtype D ) D * );2652 2653 forall( dtype DT ) DT _Atomic2654 * ?=?( _Atomic DT * restrict volatile *, DT _Atomic * ),2655 * ?=?( _Atomic DT * restrict volatile *, void * ),2656 * ?=?( _Atomic DT * restrict volatile *, forall( dtype D ) D * ),2657 * ?=?( _Atomic DT * _Atomic restrict volatile *, DT _Atomic * ),2658 * ?=?( _Atomic DT * _Atomic restrict volatile *, void * ),2659 * ?=?( _Atomic DT * _Atomic restrict volatile *, forall( dtype D ) D * );2660 2661 forall( dtype DT ) DT const2662 * ?=?( DT const * restrict volatile *, DT const * ),2663 * ?=?( DT const * restrict volatile *, void const * ),2664 * ?=?( DT const * restrict volatile *, forall( dtype D ) D * ),2665 * ?=?( DT const * _Atomic restrict volatile *, DT const * ),2666 * ?=?( DT const * _Atomic restrict volatile *, void const * ),2667 * ?=?( DT const * _Atomic restrict volatile *, forall( dtype D ) D * );2668 2669 forall( dtype DT ) DT restrict2670 * ?=?( restrict DT * restrict volatile *, DT restrict * ),2671 * ?=?( restrict DT * restrict volatile *, void * ),2672 * ?=?( restrict DT * restrict volatile *, forall( dtype D ) D * ),2673 * ?=?( restrict DT * _Atomic restrict volatile *, DT restrict * ),2674 * ?=?( restrict DT * _Atomic restrict volatile *, void * ),2675 * ?=?( restrict DT * _Atomic restrict volatile *, forall( dtype D ) D * );2676 2677 forall( dtype DT ) DT volatile2678 * ?=?( DT volatile * restrict volatile *, DT volatile * ),2679 * ?=?( DT volatile * restrict volatile *, void volatile * ),2680 * ?=?( DT volatile * restrict volatile *, forall( dtype D ) D * ),2681 * ?=?( DT volatile * _Atomic restrict volatile *, DT volatile * ),2682 * ?=?( DT volatile * _Atomic restrict volatile *, void volatile * ),2683 * ?=?( DT volatile * _Atomic restrict volatile *, forall( dtype D ) D * );2684 2685 forall( dtype DT ) DT _Atomic const2686 * ?=?( DT _Atomic const * restrict volatile *, DT _Atomic const * ),2687 * ?=?( DT _Atomic const * restrict volatile *, void const * ),2688 * ?=?( DT _Atomic const * restrict volatile *, forall( dtype D ) D * ),2689 * ?=?( DT _Atomic const * _Atomic restrict volatile *, DT _Atomic const * ),2690 * ?=?( DT _Atomic const * _Atomic restrict volatile *, void const * ),2691 * ?=?( DT _Atomic const * _Atomic restrict volatile *, forall( dtype D ) D * );2692 2693 forall( dtype DT ) DT _Atomic restrict2694 * ?=?( _Atomic restrict DT * restrict volatile *, DT _Atomic restrict * ),2695 * ?=?( _Atomic restrict DT * restrict volatile *, void * ),2696 * ?=?( _Atomic restrict DT * restrict volatile *, forall( dtype D ) D * ),2697 * ?=?( _Atomic restrict DT * _Atomic restrict volatile *, DT _Atomic restrict * ),2698 * ?=?( _Atomic restrict DT * _Atomic restrict volatile *, void * ),2699 * ?=?( _Atomic restrict DT * _Atomic restrict volatile *, forall( dtype D ) D * );2700 2701 forall( dtype DT ) DT _Atomic volatile2702 * ?=?( DT _Atomic volatile * restrict volatile *, DT _Atomic volatile * ),2703 * ?=?( DT _Atomic volatile * restrict volatile *, void volatile * ),2704 * ?=?( DT _Atomic volatile * restrict volatile *, forall( dtype D ) D * ),2705 * ?=?( DT _Atomic volatile * _Atomic restrict volatile *, DT _Atomic volatile * ),2706 * ?=?( DT _Atomic volatile * _Atomic restrict volatile *, void volatile * ),2707 * ?=?( DT _Atomic volatile * _Atomic restrict volatile *, forall( dtype D ) D * );2708 2709 forall( dtype DT ) DT const restrict2710 * ?=?( DT const restrict * restrict volatile *, DT const restrict * ),2711 * ?=?( DT const restrict * restrict volatile *, void const * ),2712 * ?=?( DT const restrict * restrict volatile *, forall( dtype D ) D * ),2713 * ?=?( DT const restrict * _Atomic restrict volatile *, DT const restrict * ),2714 * ?=?( DT const restrict * _Atomic restrict volatile *, void const * ),2715 * ?=?( DT const restrict * _Atomic restrict volatile *, forall( dtype D ) D * );2716 2717 forall( dtype DT ) DT const volatile2718 * ?=?( DT const volatile * restrict volatile *, DT const volatile * ),2719 * ?=?( DT const volatile * restrict volatile *, void const volatile * ),2720 * ?=?( DT const volatile * restrict volatile *, forall( dtype D ) D * ),2721 * ?=?( DT const volatile * _Atomic restrict volatile *, DT const volatile * ),2722 * ?=?( DT const volatile * _Atomic restrict volatile *, void const volatile * ),2723 * ?=?( DT const volatile * _Atomic restrict volatile *, forall( dtype D ) D * );2724 2725 forall( dtype DT ) DT restrict volatile2726 * ?=?( DT restrict volatile * restrict volatile *, DT restrict volatile * ),2727 * ?=?( DT restrict volatile * restrict volatile *, void volatile * ),2728 * ?=?( DT restrict volatile * restrict volatile *, forall( dtype D ) D * ),2729 * ?=?( DT restrict volatile * _Atomic restrict volatile *, DT restrict volatile * ),2730 * ?=?( DT restrict volatile * _Atomic restrict volatile *, void volatile * ),2731 * ?=?( DT restrict volatile * _Atomic restrict volatile *, forall( dtype D ) D * );2732 2733 forall( dtype DT ) DT _Atomic const restrict2734 * ?=?( DT _Atomic const restrict * restrict volatile *,2735 DT _Atomic const restrict * ),2736 * ?=?( DT _Atomic const restrict * restrict volatile *,2737 void const * ),2738 * ?=?( DT _Atomic const restrict * restrict volatile *,2739 forall( dtype D ) D * ),2740 * ?=?( DT _Atomic const restrict * _Atomic restrict volatile *,2741 DT _Atomic const restrict * ),2742 * ?=?( DT _Atomic const restrict * _Atomic restrict volatile *,2743 void const * ),2744 * ?=?( DT _Atomic const restrict * _Atomic restrict volatile *,2745 forall( dtype D ) D * );2746 2747 forall( dtype DT ) DT _Atomic const volatile2748 * ?=?( DT _Atomic const volatile * restrict volatile *,2749 DT _Atomic const volatile * ),2750 * ?=?( DT _Atomic const volatile * restrict volatile *,2751 void const volatile * ),2752 * ?=?( DT _Atomic const volatile * restrict volatile *,2753 forall( dtype D ) D * ),2754 * ?=?( DT _Atomic const volatile * _Atomic restrict volatile *,2755 DT _Atomic const volatile * ),2756 * ?=?( DT _Atomic const volatile * _Atomic restrict volatile *,2757 void const volatile * ),2758 * ?=?( DT _Atomic const volatile * _Atomic restrict volatile *,2759 forall( dtype D ) D * );2760 2761 forall( dtype DT ) DT _Atomic restrict volatile2762 * ?=?( DT _Atomic restrict volatile * restrict volatile *,2763 DT _Atomic restrict volatile * ),2764 * ?=?( DT _Atomic restrict volatile * restrict volatile *,2765 void volatile * ),2766 * ?=?( DT _Atomic restrict volatile * restrict volatile *,2767 forall( dtype D ) D * ),2768 * ?=?( DT _Atomic restrict volatile * _Atomic restrict volatile *,2769 DT _Atomic restrict volatile * ),2770 * ?=?( DT _Atomic restrict volatile * _Atomic restrict volatile *,2771 void volatile * ),2772 * ?=?( DT _Atomic restrict volatile * _Atomic restrict volatile *,2773 forall( dtype D ) D * );2774 2775 forall( dtype DT ) DT const restrict volatile2776 * ?=?( DT const restrict volatile * restrict volatile *,2777 DT const restrict volatile * ),2778 * ?=?( DT const restrict volatile * restrict volatile *,2779 void const volatile * ),2780 * ?=?( DT const restrict volatile * restrict volatile *,2781 forall( dtype D ) D * ),2782 * ?=?( DT const restrict volatile * _Atomic restrict volatile *,2783 DT const restrict volatile * ),2784 * ?=?( DT const restrict volatile * _Atomic restrict volatile *,2785 void const volatile * ),2786 * ?=?( DT const restrict volatile * _Atomic restrict volatile *,2787 forall( dtype D ) D * );2788 2789 forall( dtype DT ) DT _Atomic const restrict volatile2790 * ?=?( DT _Atomic const restrict volatile * restrict volatile *,2791 DT _Atomic const restrict volatile * ),2792 * ?=?( DT _Atomic const restrict volatile * restrict volatile *,2793 void const volatile * ),2794 * ?=?( DT _Atomic const restrict volatile * restrict volatile *,2795 forall( dtype D ) D * ),2796 * ?=?( DT _Atomic const restrict volatile * _Atomic restrict volatile *,2797 DT _Atomic const restrict volatile * ),2798 * ?=?( DT _Atomic const restrict volatile * _Atomic restrict volatile *,2799 void const volatile * ),2800 * ?=?( DT _Atomic const restrict volatile * _Atomic restrict volatile *,2801 forall( dtype D ) D * );2802 2803 forall( dtype DT ) void2804 * ?=?( void * restrict volatile *, DT * );2805 2806 forall( dtype DT ) void const2807 * ?=?( void const * restrict volatile *, DT const * );2808 2809 forall( dtype DT ) void volatile2810 * ?=?( void volatile * restrict volatile *, DT volatile * );2811 2812 forall( dtype DT ) void const volatile2813 * ?=?( void const volatile * restrict volatile *, DT const volatile * );2814 \end{lstlisting}2815 \begin{rationale}2816 The pattern of overloadings for simple assignment resembles that of pointer increment and decrement,2817 except that the polymorphic pointer assignment functions declare a \lstinline$dtype$ parameter,2818 instead of a \lstinline$type$ parameter, because the left operand may be a pointer to an incomplete2819 type.2820 \end{rationale}2821 2822 For every complete structure or union type \lstinline$S$ there exist2823 % Don't use predefined: keep this out of prelude.cf.2824 \begin{lstlisting}2825 S ?=?( S volatile *, S ), ?=?( S _Atomic volatile *, S );2826 \end{lstlisting}2827 2828 For every extended integer type \lstinline$X$ there exist2829 % Don't use predefined: keep this out of prelude.cf.2830 \begin{lstlisting}2831 X ?=?( X volatile *, X ), ?=?( X _Atomic volatile *, X );2832 \end{lstlisting}2833 2834 For every complete enumerated type \lstinline$E$ there exist2835 % Don't use predefined: keep this out of prelude.cf.2836 \begin{lstlisting}2837 E ?=?( E volatile *, int ), ?=?( E _Atomic volatile *, int );2838 \end{lstlisting}2839 \begin{rationale}2840 The right-hand argument is \lstinline$int$ because enumeration constants have type \lstinline$int$.2841 \end{rationale}2842 2843 \semantics2844 The structure assignment functions provide member-wise assignment; each non-array member and each2845 element of each array member of the right argument is assigned to the corresponding member or2846 element of the left argument using the assignment function defined for its type. All other2847 assignment functions have the same effect as the corresponding C assignment expression.2848 \begin{rationale}2849 Note that, by default, union assignment\index{deficiencies!union assignment} uses C semantics---that2850 is, bitwise copy---even if some of the union members have programmer-defined assignment functions.2851 \end{rationale}2852 2853 2854 \subsubsection{Compound assignment}2855 2856 \begin{lstlisting}2857 forall( type T ) T2858 * ?+=?( T * restrict volatile *, ptrdiff_t ),2859 * ?-=?( T * restrict volatile *, ptrdiff_t ),2860 * ?+=?( T * _Atomic restrict volatile *, ptrdiff_t ),2861 * ?-=?( T * _Atomic restrict volatile *, ptrdiff_t );2862 2863 forall( type T ) T _Atomic2864 * ?+=?( T _Atomic * restrict volatile *, ptrdiff_t ),2865 * ?-=?( T _Atomic * restrict volatile *, ptrdiff_t ),2866 * ?+=?( T _Atomic * _Atomic restrict volatile *, ptrdiff_t ),2867 * ?-=?( T _Atomic * _Atomic restrict volatile *, ptrdiff_t );2868 2869 forall( type T ) T const2870 * ?+=?( T const * restrict volatile *, ptrdiff_t ),2871 * ?-=?( T const * restrict volatile *, ptrdiff_t ),2872 * ?+=?( T const * _Atomic restrict volatile *, ptrdiff_t ),2873 * ?-=?( T const * _Atomic restrict volatile *, ptrdiff_t );2874 2875 forall( type T ) T restrict2876 * ?+=?( T restrict * restrict volatile *, ptrdiff_t ),2877 * ?-=?( T restrict * restrict volatile *, ptrdiff_t ),2878 * ?+=?( T restrict * _Atomic restrict volatile *, ptrdiff_t ),2879 * ?-=?( T restrict * _Atomic restrict volatile *, ptrdiff_t );2880 2881 forall( type T ) T volatile2882 * ?+=?( T volatile * restrict volatile *, ptrdiff_t ),2883 * ?-=?( T volatile * restrict volatile *, ptrdiff_t ),2884 * ?+=?( T volatile * _Atomic restrict volatile *, ptrdiff_t ),2885 * ?-=?( T volatile * _Atomic restrict volatile *, ptrdiff_t );2886 2887 forall( type T ) T _Atomic const2888 * ?+=?( T _Atomic const restrict volatile *, ptrdiff_t ),2889 * ?-=?( T _Atomic const restrict volatile *, ptrdiff_t ),2890 * ?+=?( T _Atomic const _Atomic restrict volatile *, ptrdiff_t ),2891 * ?-=?( T _Atomic const _Atomic restrict volatile *, ptrdiff_t );2892 2893 forall( type T ) T _Atomic restrict2894 * ?+=?( T _Atomic restrict * restrict volatile *, ptrdiff_t ),2895 * ?-=?( T _Atomic restrict * restrict volatile *, ptrdiff_t ),2896 * ?+=?( T _Atomic restrict * _Atomic restrict volatile *, ptrdiff_t ),2897 * ?-=?( T _Atomic restrict * _Atomic restrict volatile *, ptrdiff_t );2898 2899 forall( type T ) T _Atomic volatile2900 * ?+=?( T _Atomic volatile * restrict volatile *, ptrdiff_t ),2901 * ?-=?( T _Atomic volatile * restrict volatile *, ptrdiff_t ),2902 * ?+=?( T _Atomic volatile * _Atomic restrict volatile *, ptrdiff_t ),2903 * ?-=?( T _Atomic volatile * _Atomic restrict volatile *, ptrdiff_t );2904 2905 forall( type T ) T const restrict2906 * ?+=?( T const restrict * restrict volatile *, ptrdiff_t ),2907 * ?-=?( T const restrict * restrict volatile *, ptrdiff_t ),2908 * ?+=?( T const restrict * _Atomic restrict volatile *, ptrdiff_t ),2909 * ?-=?( T const restrict * _Atomic restrict volatile *, ptrdiff_t );2910 2911 forall( type T ) T const volatile2912 * ?+=?( T const volatile * restrict volatile *, ptrdiff_t ),2913 * ?-=?( T const volatile * restrict volatile *, ptrdiff_t ),2914 * ?+=?( T const volatile * _Atomic restrict volatile *, ptrdiff_t ),2915 * ?-=?( T const volatile * _Atomic restrict volatile *, ptrdiff_t );2916 2917 forall( type T ) T restrict volatile2918 * ?+=?( T restrict volatile * restrict volatile *, ptrdiff_t ),2919 * ?-=?( T restrict volatile * restrict volatile *, ptrdiff_t ),2920 * ?+=?( T restrict volatile * _Atomic restrict volatile *, ptrdiff_t ),2921 * ?-=?( T restrict volatile * _Atomic restrict volatile *, ptrdiff_t );2922 2923 forall( type T ) T _Atomic const restrict2924 * ?+=?( T _Atomic const restrict * restrict volatile *, ptrdiff_t ),2925 * ?-=?( T _Atomic const restrict * restrict volatile *, ptrdiff_t ),2926 * ?+=?( T _Atomic const restrict * _Atomic restrict volatile *, ptrdiff_t ),2927 * ?-=?( T _Atomic const restrict * _Atomic restrict volatile *, ptrdiff_t );2928 2929 forall( type T ) T _Atomic const volatile2930 * ?+=?( T _Atomic const volatile * restrict volatile *, ptrdiff_t ),2931 * ?-=?( T _Atomic const volatile * restrict volatile *, ptrdiff_t ),2932 * ?+=?( T _Atomic const volatile * _Atomic restrict volatile *, ptrdiff_t ),2933 * ?-=?( T _Atomic const volatile * _Atomic restrict volatile *, ptrdiff_t );2934 2935 forall( type T ) T _Atomic restrict volatile2936 * ?+=?( T _Atomic restrict volatile * restrict volatile *, ptrdiff_t ),2937 * ?-=?( T _Atomic restrict volatile * restrict volatile *, ptrdiff_t ),2938 * ?+=?( T _Atomic restrict volatile * _Atomic restrict volatile *, ptrdiff_t ),2939 * ?-=?( T _Atomic restrict volatile * _Atomic restrict volatile *, ptrdiff_t );2940 2941 forall( type T ) T const restrict volatile2942 * ?+=?( T const restrict volatile * restrict volatile *, ptrdiff_t ),2943 * ?-=?( T const restrict volatile * restrict volatile *, ptrdiff_t ),2944 * ?+=?( T const restrict volatile * _Atomic restrict volatile *, ptrdiff_t ),2945 * ?-=?( T const restrict volatile * _Atomic restrict volatile *, ptrdiff_t );2946 2947 forall( type T ) T _Atomic const restrict volatile2948 * ?+=?( T _Atomic const restrict volatile * restrict volatile *, ptrdiff_t ),2949 * ?-=?( T _Atomic const restrict volatile * restrict volatile *, ptrdiff_t ),2950 * ?+=?( T _Atomic const restrict volatile * _Atomic restrict volatile *, ptrdiff_t ),2951 * ?-=?( T _Atomic const restrict volatile * _Atomic restrict volatile *, ptrdiff_t );2952 2953 _Bool2954 ?*=?( _Bool volatile *, _Bool ),2955 ?/=?( _Bool volatile *, _Bool ),2956 ?+=?( _Bool volatile *, _Bool ),2957 ?-=?( _Bool volatile *, _Bool ),2958 ?%=?( _Bool volatile *, _Bool ),2959 ?<<=?( _Bool volatile *, int ),2960 ?>>=?( _Bool volatile *, int ),2961 ?&=?( _Bool volatile *, _Bool ),2962 ?^=?( _Bool volatile *, _Bool ),2963 ?|=?( _Bool volatile *, _Bool );2964 char2965 ?*=?( char volatile *, char ),2966 ?/=?( char volatile *, char ),2967 ?+=?( char volatile *, char ),2968 ?-=?( char volatile *, char ),2969 ?%=?( char volatile *, char ),2970 ?<<=?( char volatile *, int ),2971 ?>>=?( char volatile *, int ),2972 ?&=?( char volatile *, char ),2973 ?^=?( char volatile *, char ),2974 ?|=?( char volatile *, char );2975 unsigned char2976 ?*=?( unsigned char volatile *, unsigned char ),2977 ?/=?( unsigned char volatile *, unsigned char ),2978 ?+=?( unsigned char volatile *, unsigned char ),2979 ?-=?( unsigned char volatile *, unsigned char ),2980 ?%=?( unsigned char volatile *, unsigned char ),2981 ?<<=?( unsigned char volatile *, int ),2982 ?>>=?( unsigned char volatile *, int ),2983 ?&=?( unsigned char volatile *, unsigned char ),2984 ?^=?( unsigned char volatile *, unsigned char ),2985 ?|=?( unsigned char volatile *, unsigned char );2986 signed char2987 ?*=?( signed char volatile *, signed char ),2988 ?/=?( signed char volatile *, signed char ),2989 ?+=?( signed char volatile *, signed char ),2990 ?-=?( signed char volatile *, signed char ),2991 ?%=?( signed char volatile *, signed char ),2992 ?<<=?( signed char volatile *, int ),2993 ?>>=?( signed char volatile *, int ),2994 ?&=?( signed char volatile *, signed char ),2995 ?^=?( signed char volatile *, signed char ),2996 ?|=?( signed char volatile *, signed char );2997 short int2998 ?*=?( short int volatile *, short int ),2999 ?/=?( short int volatile *, short int ),3000 ?+=?( short int volatile *, short int ),3001 ?-=?( short int volatile *, short int ),3002 ?%=?( short int volatile *, short int ),3003 ?<<=?( short int volatile *, int ),3004 ?>>=?( short int volatile *, int ),3005 ?&=?( short int volatile *, short int ),3006 ?^=?( short int volatile *, short int ),3007 ?|=?( short int volatile *, short int );3008 unsigned short int3009 ?*=?( unsigned short int volatile *, unsigned short int ),3010 ?/=?( unsigned short int volatile *, unsigned short int ),3011 ?+=?( unsigned short int volatile *, unsigned short int ),3012 ?-=?( unsigned short int volatile *, unsigned short int ),3013 ?%=?( unsigned short int volatile *, unsigned short int ),3014 ?<<=?( unsigned short int volatile *, int ),3015 ?>>=?( unsigned short int volatile *, int ),3016 ?&=?( unsigned short int volatile *, unsigned short int ),3017 ?^=?( unsigned short int volatile *, unsigned short int ),3018 ?|=?( unsigned short int volatile *, unsigned short int );3019 int3020 ?*=?( int volatile *, int ),3021 ?/=?( int volatile *, int ),3022 ?+=?( int volatile *, int ),3023 ?-=?( int volatile *, int ),3024 ?%=?( int volatile *, int ),3025 ?<<=?( int volatile *, int ),3026 ?>>=?( int volatile *, int ),3027 ?&=?( int volatile *, int ),3028 ?^=?( int volatile *, int ),3029 ?|=?( int volatile *, int );3030 unsigned int3031 ?*=?( unsigned int volatile *, unsigned int ),3032 ?/=?( unsigned int volatile *, unsigned int ),3033 ?+=?( unsigned int volatile *, unsigned int ),3034 ?-=?( unsigned int volatile *, unsigned int ),3035 ?%=?( unsigned int volatile *, unsigned int ),3036 ?<<=?( unsigned int volatile *, int ),3037 ?>>=?( unsigned int volatile *, int ),3038 ?&=?( unsigned int volatile *, unsigned int ),3039 ?^=?( unsigned int volatile *, unsigned int ),3040 ?|=?( unsigned int volatile *, unsigned int );3041 long int3042 ?*=?( long int volatile *, long int ),3043 ?/=?( long int volatile *, long int ),3044 ?+=?( long int volatile *, long int ),3045 ?-=?( long int volatile *, long int ),3046 ?%=?( long int volatile *, long int ),3047 ?<<=?( long int volatile *, int ),3048 ?>>=?( long int volatile *, int ),3049 ?&=?( long int volatile *, long int ),3050 ?^=?( long int volatile *, long int ),3051 ?|=?( long int volatile *, long int );3052 unsigned long int3053 ?*=?( unsigned long int volatile *, unsigned long int ),3054 ?/=?( unsigned long int volatile *, unsigned long int ),3055 ?+=?( unsigned long int volatile *, unsigned long int ),3056 ?-=?( unsigned long int volatile *, unsigned long int ),3057 ?%=?( unsigned long int volatile *, unsigned long int ),3058 ?<<=?( unsigned long int volatile *, int ),3059 ?>>=?( unsigned long int volatile *, int ),3060 ?&=?( unsigned long int volatile *, unsigned long int ),3061 ?^=?( unsigned long int volatile *, unsigned long int ),3062 ?|=?( unsigned long int volatile *, unsigned long int );3063 long long int3064 ?*=?( long long int volatile *, long long int ),3065 ?/=?( long long int volatile *, long long int ),3066 ?+=?( long long int volatile *, long long int ),3067 ?-=?( long long int volatile *, long long int ),3068 ?%=?( long long int volatile *, long long int ),3069 ?<<=?( long long int volatile *, int ),3070 ?>>=?( long long int volatile *, int ),3071 ?&=?( long long int volatile *, long long int ),3072 ?^=?( long long int volatile *, long long int ),3073 ?|=?( long long int volatile *, long long int );3074 unsigned long long int3075 ?*=?( unsigned long long int volatile *, unsigned long long int ),3076 ?/=?( unsigned long long int volatile *, unsigned long long int ),3077 ?+=?( unsigned long long int volatile *, unsigned long long int ),3078 ?-=?( unsigned long long int volatile *, unsigned long long int ),3079 ?%=?( unsigned long long int volatile *, unsigned long long int ),3080 ?<<=?( unsigned long long int volatile *, int ),3081 ?>>=?( unsigned long long int volatile *, int ),3082 ?&=?( unsigned long long int volatile *, unsigned long long int ),3083 ?^=?( unsigned long long int volatile *, unsigned long long int ),3084 ?|=?( unsigned long long int volatile *, unsigned long long int );3085 float3086 ?*=?( float volatile *, float ),3087 ?/=?( float volatile *, float ),3088 ?+=?( float volatile *, float ),3089 ?-=?( float volatile *, float );3090 double3091 ?*=?( double volatile *, double ),3092 ?/=?( double volatile *, double ),3093 ?+=?( double volatile *, double ),3094 ?-=?( double volatile *, double );3095 long double3096 ?*=?( long double volatile *, long double ),3097 ?/=?( long double volatile *, long double ),3098 ?+=?( long double volatile *, long double ),3099 ?-=?( long double volatile *, long double );3100 _Complex float3101 ?*=?( _Complex float volatile *, _Complex float ),3102 ?/=?( _Complex float volatile *, _Complex float ),3103 ?+=?( _Complex float volatile *, _Complex float ),3104 ?-=?( _Complex float volatile *, _Complex float );3105 _Complex double3106 ?*=?( _Complex double volatile *, _Complex double ),3107 ?/=?( _Complex double volatile *, _Complex double ),3108 ?+=?( _Complex double volatile *, _Complex double ),3109 ?-=?( _Complex double volatile *, _Complex double );3110 _Complex long double3111 ?*=?( _Complex long double volatile *, _Complex long double ),3112 ?/=?( _Complex long double volatile *, _Complex long double ),3113 ?+=?( _Complex long double volatile *, _Complex long double ),3114 ?-=?( _Complex long double volatile *, _Complex long double );3115 \end{lstlisting}3116 3117 For every extended integer type \lstinline$X$ there exist3118 % Don't use predefined: keep this out of prelude.cf.3119 \begin{lstlisting}3120 ?*=?( X volatile *, X ),3121 ?/=?( X volatile *, X ),3122 ?+=?( X volatile *, X ),3123 ?-=?( X volatile *, X ),3124 ?%=?( X volatile *, X ),3125 ?<<=?( X volatile *, int ),3126 ?>>=?( X volatile *, int ),3127 ?&=?( X volatile *, X ),3128 ?^=?( X volatile *, X ),3129 ?|=?( X volatile *, X );3130 \end{lstlisting}3131 3132 For every complete enumerated type \lstinline$E$ there exist3133 % Don't use predefined: keep this out of prelude.cf.3134 \begin{lstlisting}3135 ?*=?( E volatile *, E ),3136 ?/=?( E volatile *, E ),3137 ?+=?( E volatile *, E ),3138 ?-=?( E volatile *, E ),3139 ?%=?( E volatile *, E ),3140 ?<<=?( E volatile *, int ),3141 ?>>=?( E volatile *, int ),3142 ?&=?( E volatile *, E ),3143 ?^=?( E volatile *, E ),3144 ?|=?( E volatile *, E );3145 \end{lstlisting}3146 3147 3148 \subsection{Comma operator}3149 3150 \begin{syntax}3151 \lhs{expression}3152 \rhs \nonterm{assignment-expression}3153 \rhs \nonterm{expression} \lstinline$,$ \nonterm{assignment-expression}3154 \end{syntax}3155 3156 \semantics3157 In the comma expression ``\lstinline$a, b$'', the first operand is interpreted as3158 ``\lstinline$( void )(a)$'', which shall be unambiguous\index{ambiguous interpretation}. The3159 interpretations of the expression are the interpretations of the second operand.3160 3161 3162 \section{Constant expressions}3163 3164 3165 \section{Declarations}3166 3167 \begin{syntax}3168 \oldlhs{declaration}3169 \rhs \nonterm{type-declaration}3170 \rhs \nonterm{spec-definition}3171 \end{syntax}3172 3173 \constraints3174 If an identifier has no linkage\index{no linkage}, there shall be no more than one declaration of3175 the identifier ( in a declarator or type specifier ) with compatible types in the same scope and in3176 the same name space, except that:3177 \begin{itemize}3178 \item3179 a typedef name may be redefined to denote the same type as it currently does, provided that type is3180 not a variably modified type;3181 \item3182 tags may be redeclared as specified in section 6.7.2.3 of the {\c11} standard.3183 \end{itemize}3184 \begin{rationale}3185 This constraint adds the phrase ``with compatible types'' to the {\c11} constraint, to allow3186 overloading.3187 \end{rationale}3188 3189 An identifier declared by a type declaration shall not be redeclared as a parameter in a function3190 definition whose declarator includes an identifier list.3191 \begin{rationale}3192 This restriction echos {\c11}'s ban on the redeclaration of typedef names as parameters. This3193 avoids an ambiguity between old-style function declarations and new-style function prototypes:3194 \begin{lstlisting}3195 void f( Complex, // ... 3000 characters ...3196 void g( Complex, // ... 3000 characters ...3197 int Complex; { ... }3198 \end{lstlisting}3199 Without the rule, \lstinline$Complex$ would be a type in the first case, and a parameter name in the3200 second.3201 \end{rationale}3202 3203 3204 \setcounter{subsection}{1}3205 \subsection{Type specifiers}3206 3207 \begin{syntax}3208 \oldlhs{type-specifier}3209 \rhs \nonterm{forall-specifier}3210 \end{syntax}3211 3212 \semantics3213 Forall specifiers are discussed in \VRef{forall}.3214 3215 3216 \subsubsection{Structure and union specifiers}3217 3218 \semantics3219 \CFA extends the {\c11} definition of \define{anonymous structure} to include structure3220 specifiers with tags, and extends the {\c11} definition of \define{anonymous union} to include union3221 specifiers with tags.3222 \begin{rationale}3223 This extension imitates an extension in the Plan 9 C compiler \cite{Thompson90new}.3224 \end{rationale}3225 3226 \examples3227 \begin{lstlisting}3228 struct point {@\impl{point}@3229 int x, y;3230 };3231 struct color_point {@\impl{color_point}@3232 enum { RED, BLUE, GREEN } color;3233 struct point;3234 };3235 struct color_point cp;3236 cp.x = 0;3237 cp.color = RED;3238 3239 struct literal {@\impl{literal}@3240 enum { NUMBER, STRING } tag;3241 union {3242 double n;3243 char *s;3244 };3245 };3246 struct literal *next;3247 int length;3248 extern int strlen( const char * );3249 ...3250 if ( next->tag == STRING ) length = strlen( next->s );3251 \end{lstlisting}3252 3253 3254 \setcounter{subsubsection}{4}3255 \subsubsection{Forall specifiers}\label{forall}3256 3257 \begin{syntax}3258 \lhs{forall-specifier}3259 \rhs \lstinline$forall$ \lstinline$($ \nonterm{type-parameter-list} \lstinline$)$3260 \end{syntax}3261 3262 \constraints3263 If the \nonterm{declaration-specifiers} of a declaration that contains a \nonterm{forall-specifier}3264 declares a structure or union tag, the types of the members of the structure or union shall not use3265 any of the type identifiers declared by the \nonterm{type-parameter-list}.3266 \begin{rationale}3267 This sort of declaration is illegal because the scope of the type identifiers ends at the end of the3268 declaration, but the scope of the structure tag does not.3269 \begin{lstlisting}3270 forall( type T ) struct Pair { T a, b; } mkPair( T, T ); // illegal3271 \end{lstlisting}3272 If an instance of \lstinline$struct Pair$ was declared later in the current scope, what would the3273 members' type be?3274 \end{rationale}3275 3276 \semantics3277 The \nonterm{type-parameter-list}s and assertions of the \nonterm{forall-specifier}s declare type3278 identifiers, function and object identifiers with no linkage\index{no linkage}.3279 3280 If, in the declaration ``\lstinline$T D1$'', \lstinline$T$ contains \nonterm{forall-specifier}s and3281 \lstinline$D1$ has the form3282 \begin{lstlisting}3283 D( @\normalsize\nonterm{parameter-type-list}@ )3284 \end{lstlisting}3285 then a type identifier declared by one of the \nonterm{forall-specifier}s is an \define{inferred3286 parameter} of the function declarator if and only if it is not an inferred parameter of a function3287 declarator in \lstinline$D$, and it is used in the type of a parameter in the following3288 \nonterm{type-parameter-list} or it and an inferred parameter are used as arguments of a3289 specification\index{specification} in one of the \nonterm{forall-specifier}s. The identifiers3290 declared by assertions that use an inferred parameter of a function declarator are assertion3291 parameters\index{assertion parameters} of that function declarator.3292 \begin{rationale}3293 Since every inferred parameter is used by some parameter, inference can be understood as a single3294 bottom-up pass over the expression tree, that only needs to apply local reasoning at each node.3295 3296 If this restriction were lifted, it would be possible to write3297 \begin{lstlisting}3298 forall( type T ) T * alloc( void );@\use{alloc}@3299 int *p = alloc();3300 \end{lstlisting}3301 Here \lstinline$alloc()$ would receive \lstinline$int$ as an inferred argument, and return an3302 \lstinline$int *$. In general, if a call to \lstinline$alloc()$ is a subexpression of an expression3303 involving polymorphic functions and overloaded identifiers, there could be considerable distance3304 between the call and the subexpression that causes \lstinline$T$ to be bound.3305 3306 With the current restriction, \lstinline$alloc()$ must be given an argument that determines3307 \lstinline$T$:3308 \begin{lstlisting}3309 forall( type T ) T * alloc( T initial_value );@\use{alloc}@3310 \end{lstlisting}3311 \end{rationale}3312 3313 If a function declarator is part of a function definition, its inferred parameters and assertion3314 parameters have block scope\index{block scope}; otherwise, identifiers declared by assertions have a3315 \define{declaration scope}, which terminates at the end of the \nonterm{declaration}.3316 3317 A function type that has at least one inferred parameter is a \define{polymorphic function} type.3318 Function types with no inferred parameters are \define{monomorphic function} types. One function3319 type is \define{less polymorphic} than another if it has fewer inferred parameters, or if it has the3320 same number of inferred parameters and fewer of its explicit parameters have types that depend on an3321 inferred parameter.3322 3323 The names of inferred parameters and the order of identifiers in forall specifiers are not relevant3324 to polymorphic function type compatibility. Let $f$ and $g$ be two polymorphic function types with3325 the same number of inferred parameters, and let $f_i$ and $g_i$ be the inferred parameters of $f$3326 and $g$ in their order of occurance in the function types' \nonterm{parameter-type-list}s. Let $f'$3327 be $f$ with every occurrence of $f_i$ replaced by $g_i$, for all $i$. Then $f$ and $g$ are3328 compatible types\index{compatible type} if $f'$'s and $g$'s return types and parameter lists are3329 compatible, and if for every assertion parameter of $f'$ there is an assertion parameter in $g$ with3330 the same identifier and compatible type, and vice versa.3331 3332 \examples3333 Consider these analogous monomorphic and polymorphic declarations.3334 \begin{lstlisting}3335 int fi( int );3336 forall( type T ) T fT( T );3337 \end{lstlisting}3338 \lstinline$fi()$ takes an \lstinline$int$ and returns an \lstinline$int$. \lstinline$fT()$ takes a3339 \lstinline$T$ and returns a \lstinline$T$, for any type \lstinline$T$.3340 \begin{lstlisting}3341 int (*pfi )( int ) = fi;3342 forall( type T ) T (*pfT )( T ) = fT;3343 \end{lstlisting}3344 \lstinline$pfi$ and \lstinline$pfT$ are pointers to functions. \lstinline$pfT$ is not3345 polymorphic, but the function it points at is.3346 \begin{lstlisting}3347 int (*fvpfi( void ))( int ) {3348 return pfi;3349 }3350 forall( type T ) T (*fvpfT( void ))( T ) {3351 return pfT;3352 }3353 \end{lstlisting}3354 \lstinline$fvpfi()$ and \lstinline$fvpfT()$ are functions taking no arguments and returning pointers3355 to functions. \lstinline$fvpfT()$ is monomorphic, but the function that its return value points3356 at is polymorphic.3357 \begin{lstlisting}3358 forall( type T ) int ( *fTpfi( T ) )( int );3359 forall( type T ) T ( *fTpfT( T ) )( T );3360 forall( type T, type U ) U ( *fTpfU( T ) )( U );3361 \end{lstlisting}3362 \lstinline$fTpfi()$ is a polymorphic function that returns a pointer to a monomorphic function3363 taking an integer and returning an integer. It could return \lstinline$pfi$. \lstinline$fTpfT()$3364 is subtle: it is a polymorphic function returning a \emph{monomorphic} function taking and returning3365 \lstinline$T$, where \lstinline$T$ is an inferred parameter of \lstinline$fTpfT()$. For instance,3366 in the expression ``\lstinline$fTpfT(17)$'', \lstinline$T$ is inferred to be \lstinline$int$, and3367 the returned value would have type \lstinline$int ( * )( int )$. ``\lstinline$fTpfT(17)(13)$'' and3368 ``\lstinline$fTpfT("yes")("no")$'' are legal, but ``\lstinline$fTpfT(17)("no")$'' is illegal.3369 \lstinline$fTpfU()$ is polymorphic ( in type \lstinline$T$), and returns a pointer to a function that3370 is polymorphic ( in type \lstinline$U$). ``\lstinline$f5(17)("no")$'' is a legal expression of type3371 \lstinline$char *$.3372 \begin{lstlisting}3373 forall( type T, type U, type V ) U * f( T *, U, V * const );3374 forall( type U, type V, type W ) U * g( V *, U, W * const );3375 \end{lstlisting}3376 The functions \lstinline$f()$ and \lstinline$g()$ have compatible types. Let \(f\) and \(g\) be3377 their types; then \(f_1\) = \lstinline$T$, \(f_2\) = \lstinline$U$, \(f_3\) = \lstinline$V$, \(g_1\)3378 = \lstinline$V$, \(g_2\) = \lstinline$U$, and \(g_3\) = \lstinline$W$. Replacing every \(f_i\)3379 by \(g_i\) in \(f\) gives3380 \begin{lstlisting}3381 forall( type V, type U, type W ) U * f( V *, U, W * const );3382 \end{lstlisting}3383 which has a return type and parameter list that is compatible with \(g\).3384 \begin{rationale}3385 The word ``\lstinline$type$'' in a forall specifier is redundant at the moment, but I want to leave3386 room for inferred parameters of ordinary types in case parameterized types get added one day.3387 3388 Even without parameterized types, I might try to allow3389 \begin{lstlisting}3390 forall( int n ) int sum( int vector[n] );3391 \end{lstlisting}3392 but C currently rewrites array parameters as pointer parameters, so the effects of such a change3393 require more thought.3394 \end{rationale}3395 3396 \begin{rationale}3397 A polymorphic declaration must do two things: it must introduce type parameters, and it must apply3398 assertions to those types. Adding this to existing C declaration syntax and semantics was delicate,3399 and not entirely successful.3400 3401 C depends on declaration-before-use, so a forall specifier must introduce type names before they can3402 be used in the declaration specifiers. This could be done by making the forall specifier part of3403 the declaration specifiers, or by making it a new introductory clause of declarations.3404 3405 Assertions are also part of polymorphic function types, because it must be clear which functions3406 have access to the assertion parameters declared by the assertions. All attempts to put assertions3407 inside an introductory clause produced complex semantics and confusing code. Building them into the3408 declaration specifiers could be done by placing them in the function's parameter list, or in a3409 forall specifier that is a declaration specifier. Assertions are also used with type parameters of3410 specifications, and by type declarations. For consistency's sake it seems best to attach assertions3411 to the type declarations in forall specifiers, which means that forall specifiers must be3412 declaration specifiers.3413 \end{rationale}3414 %HERE3415 3416 3417 \subsection{Type qualifiers}3418 3419 \CFA defines a new type qualifier \lstinline$lvalue$\impl{lvalue}\index{lvalue}.3420 \begin{syntax}3421 \oldlhs{type-qualifier}3422 \rhs \lstinline$lvalue$3423 \end{syntax}3424 3425 \constraints3426 \lstinline$restrict$\index{register@{\lstinline$restrict$}} Types other than type parameters and3427 pointer types whose referenced type is an object type shall not be restrict-qualified.3428 3429 \semantics3430 An object's type may be a restrict-qualified type parameter. \lstinline$restrict$ does not3431 establish any special semantics in that case.3432 3433 \begin{rationale}3434 \CFA loosens the constraint on the restrict qualifier so that restrict-qualified pointers may be3435 passed to polymorphic functions.3436 \end{rationale}3437 3438 \lstinline$lvalue$ may be used to qualify the return type of a function type. Let \lstinline$T$ be3439 an unqualified version of a type; then the result of calling a function with return type3440 \lstinline$lvalue T$ is a modifiable lvalue\index{modifiable lvalue} of type \lstinline$T$.3441 \lstinline$const$\use{const} and \lstinline$volatile$\use{volatile} qualifiers may also be added to3442 indicate that the function result is a constant or volatile lvalue.3443 \begin{rationale}3444 The \lstinline$const$ and \lstinline$volatile$ qualifiers can only be sensibly used to qualify the3445 return type of a function if the \lstinline$lvalue$ qualifier is also used.3446 \end{rationale}3447 3448 An {lvalue}-qualified type may be used in a cast expression\index{cast expression} if the operand is3449 an lvalue; the result of the expression is an lvalue.3450 3451 \begin{rationale}3452 \lstinline$lvalue$ provides some of the functionality of {\CC}'s ``\lstinline$T&$'' ( reference to3453 object of type \lstinline$T$) type. Reference types have four uses in {\CC}.3454 \begin{itemize}3455 \item3456 They are necessary for user-defined operators that return lvalues, such as ``subscript'' and3457 ``dereference''.3458 3459 \item3460 A reference can be used to define an alias for a complicated lvalue expression, as a way of getting3461 some of the functionality of the Pascal \lstinline$with$ statement. The following {\CC} code gives3462 an example.3463 \begin{lstlisting}3464 {3465 char &code = long_name.some_field[i].data->code;3466 code = toupper( code );3467 }3468 \end{lstlisting}3469 This is not very useful.3470 3471 \item3472 A reference parameter can be used to allow a function to modify an argument without forcing the3473 caller to pass the address of the argument. This is most useful for user-defined assignment3474 operators. In {\CC}, plain assignment is done by a function called ``\lstinline$operator=$'', and3475 the two expressions3476 \begin{lstlisting}3477 a = b;3478 operator=( a, b );3479 \end{lstlisting}3480 are equivalent. If \lstinline$a$ and \lstinline$b$ are of type \lstinline$T$, then the first3481 parameter of \lstinline$operator=$ must have type ``\lstinline$T&$''. It cannot have type3482 \lstinline$T$, because then assignment couldn't alter the variable, and it can't have type3483 ``\lstinline$T *$'', because the assignment would have to be written ``\lstinline$&a = b;$''.3484 3485 In the case of user-defined operators, this could just as well be handled by using pointer types and3486 by changing the rewrite rules so that ``\lstinline$a = b;$'' is equivalent to3487 ``\lstinline$operator=(&( a), b )$''. Reference parameters of ``normal'' functions are Bad Things,3488 because they remove a useful property of C function calls: an argument can only be modified by a3489 function if it is preceded by ``\lstinline$&$''.3490 3491 \item3492 References to const-qualified\index{const-qualified} types can be used instead of value parameters.3493 Given the {\CC} function call ``\lstinline$fiddle( a_thing )$'', where the type of3494 \lstinline$a_thing$ is \lstinline$Thing$, the type of \lstinline$fiddle$ could be either of3495 \begin{lstlisting}3496 void fiddle( Thing );3497 void fiddle( const Thing & );3498 \end{lstlisting}3499 If the second form is used, then constructors and destructors are not invoked to create a temporary3500 variable at the call site ( and it is bad style for the caller to make any assumptions about such3501 things), and within \lstinline$fiddle$ the parameter is subject to the usual problems caused by3502 aliases. The reference form might be chosen for efficiency's sake if \lstinline$Thing$s are too3503 large or their constructors or destructors are too expensive. An implementation may switch between3504 them without causing trouble for well-behaved clients. This leaves the implementor to define ``too3505 large'' and ``too expensive''.3506 3507 I propose to push this job onto the compiler by allowing it to implement3508 \begin{lstlisting}3509 void fiddle( const volatile Thing );3510 \end{lstlisting}3511 with call-by-reference. Since it knows all about the size of \lstinline$Thing$s and the parameter3512 passing mechanism, it should be able to come up with a better definition of ``too large'', and may3513 be able to make a good guess at ``too expensive''.3514 \end{itemize}3515 3516 In summary, since references are only really necessary for returning lvalues, I'll only provide3517 lvalue functions.3518 \end{rationale}3519 3520 3521 \setcounter{subsection}{8}3522 \subsection{Initialization}3523 3524 An expression that is used as an \nonterm{initializer} is treated as being cast to the type of the3525 object being initialized. An expression used in an \nonterm{initializer-list} is treated as being3526 cast to the type of the aggregate member that it initializes. In either case the cast must have a3527 single unambiguous interpretation\index{interpretations}.3528 3529 3530 \setcounter{subsection}{10}3531 \subsection{Specification definitions}3532 3533 \begin{syntax}3534 \lhs{spec-definition}3535 \rhs \lstinline$spec$ \nonterm{identifier}3536 \lstinline$($ \nonterm{type-parameter-list} \lstinline$)$3537 \lstinline${$ \nonterm{spec-declaration-list}\opt \lstinline$}$3538 \lhs{spec-declaration-list}3539 \rhs \nonterm{spec-declaration} \lstinline$;$3540 \rhs \nonterm{spec-declaration-list} \nonterm{spec-declaration} \lstinline$;$3541 \lhs{spec-declaration}3542 \rhs \nonterm{specifier-qualifier-list} \nonterm{declarator-list}3543 \lhs{declarator-list}3544 \rhs \nonterm{declarator}3545 \rhs \nonterm{declarator-list} \lstinline$,$ \nonterm{declarator}3546 \end{syntax}3547 \begin{rationale}3548 The declarations allowed in a specification are much the same as those allowed in a structure,3549 except that bit fields are not allowed, and incomplete types\index{incomplete types} and function3550 types are allowed.3551 \end{rationale}3552 3553 \semantics3554 A \define{specification definition} defines a name for a \define{specification}: a parameterized3555 collection of object and function declarations.3556 3557 The declarations in a specification consist of the declarations in the3558 \nonterm{spec-declaration-list} and declarations produced by any assertions in the3559 \nonterm{spec-parameter-list}. If the collection contains two declarations that declare the same3560 identifier and have compatible types, they are combined into one declaration with the composite type3561 constructed from the two types.3562 3563 3564 \subsubsection{Assertions}3565 \begin{syntax}3566 \lhs{assertion-list}3567 \rhs \nonterm{assertion}3568 \rhs \nonterm{assertion-list} \nonterm{assertion}3569 \lhs{assertion}3570 \rhs \lstinline$|$ \nonterm{identifier} \lstinline$($ \nonterm{type-name-list} \lstinline$)$3571 \rhs \lstinline$|$ \nonterm{spec-declaration}3572 \lhs{type-name-list}3573 \rhs \nonterm{type-name}3574 \rhs \nonterm{type-name-list} \lstinline$,$ \nonterm{type-name}3575 \end{syntax}3576 3577 \constraints3578 The \nonterm{identifier} in an assertion that is not a \nonterm{spec-declaration} shall be the name3579 of a specification. The \nonterm{type-name-list} shall contain one \nonterm{type-name} argument for3580 each \nonterm{type-parameter} in that specification's \nonterm{spec-parameter-list}. If the3581 \nonterm{type-parameter} uses type-class \lstinline$type$\use{type}, the argument shall be the type3582 name of an object type\index{object types}; if it uses \lstinline$dtype$, the argument shall be the3583 type name of an object type or an incomplete type\index{incomplete types}; and if it uses3584 \lstinline$ftype$, the argument shall be the type name of a function type\index{function types}.3585 3586 \semantics3587 An \define{assertion} is a declaration of a collection of objects and functions, called3588 \define{assertion parameters}.3589 3590 The assertion parameters produced by an assertion that applies the name of a specification to type3591 arguments are found by taking the declarations specified in the specification and treating each of3592 the specification's parameters as a synonym for the corresponding \nonterm{type-name} argument.3593 3594 The collection of assertion parameters produced by the \nonterm{assertion-list} are found by3595 combining the declarations produced by each assertion. If the collection contains two declarations3596 that declare the same identifier and have compatible types, they are combined into one declaration3597 with the composite type\index{composite type} constructed from the two types.3598 3599 \examples3600 \begin{lstlisting}3601 forall( type T | T ?*?( T, T ))@\use{?*?}@3602 T square( T val ) {@\impl{square}@3603 return val + val;3604 }3605 3606 context summable( type T ) {@\impl{summable}@3607 T ?+=?( T *, T );@\use{?+=?}@3608 const T 0;@\use{0}@3609 };3610 context list_of( type List, type Element ) {@\impl{list_of}@3611 Element car( List );3612 List cdr( List );3613 List cons( Element, List );3614 List nil;3615 int is_nil( List );3616 };3617 context sum_list( type List, type Element | summable( Element ) | list_of( List, Element ) ) {};3618 \end{lstlisting}3619 \lstinline$sum_list$ contains seven declarations, which describe a list whose elements can be added3620 up. The assertion ``\lstinline$|sum_list( i_list, int )$''\use{sum_list} produces the assertion3621 parameters3622 \begin{lstlisting}3623 int ?+=?( int *, int );3624 const int 0;3625 int car( i_list );3626 i_list cdr( i_list );3627 i_list cons( int, i_list );3628 i_list nil;3629 int is_nil;3630 \end{lstlisting}3631 3632 \subsection{Type declarations}3633 \begin{syntax}3634 \lhs{type-parameter-list}3635 \rhs \nonterm{type-parameter}3636 \rhs \nonterm{type-parameter-list} \lstinline$,$ \nonterm{type-parameter}3637 \lhs{type-parameter}3638 \rhs \nonterm{type-class} \nonterm{identifier} \nonterm{assertion-list}\opt3639 \lhs{type-class}3640 \rhs \lstinline$type$3641 \rhs \lstinline$dtype$3642 \rhs \lstinline$ftype$3643 \lhs{type-declaration}3644 \rhs \nonterm{storage-class-specifier}\opt \lstinline$type$ \nonterm{type-declarator-list} \verb|;|3645 \lhs{type-declarator-list}3646 \rhs \nonterm{type-declarator}3647 \rhs \nonterm{type-declarator-list} \lstinline$,$ \nonterm{type-declarator}3648 \lhs{type-declarator}3649 \rhs \nonterm{identifier} \nonterm{assertion-list}\opt \lstinline$=$ \nonterm{type-name}3650 \rhs \nonterm{identifier} \nonterm{assertion-list}\opt3651 \end{syntax}3652 3653 \constraints3654 If a type declaration has block scope, and the declared identifier has external or internal linkage,3655 the declaration shall have no initializer for the identifier.3656 3657 \semantics3658 A \nonterm{type-parameter} or a \nonterm{type-declarator} declares an identifier to be a type3659 name\index{type names} for a type incompatible with all other types.3660 3661 An identifier declared by a \nonterm{type-parameter} has no linkage\index{no linkage}. Identifiers3662 declared with type-class \lstinline$type$\use{type} are object types\index{object types}; those3663 declared with type-class \lstinline$dtype$\use{dtype} are incomplete types\index{incomplete types};3664 and those declared with type-class \lstinline$ftype$\use{ftype} are function types\index{function3665 types}. The identifier has block scope\index{block scope} that terminates at the end of the3666 \nonterm{spec-declaration-list} or polymorphic function that contains the \nonterm{type-parameter}.3667 3668 A \nonterm{type-declarator} with an initializer\index{initializer} is a \define{type definition}.3669 The declared identifier is an incomplete type\index{incomplete types} within the initializer, and an3670 object type\index{object types} after the end of the initializer. The type in the initializer is3671 called the \define{implementation type}. Within the scope of the declaration, implicit3672 conversions\index{implicit conversions} can be performed between the defined type and the3673 implementation type, and between pointers to the defined type and pointers to the implementation3674 type.3675 3676 A type declaration without an initializer\index{initializer} and without a storage-class3677 specifier\index{storage-class specifiers} or with storage-class specifier3678 \lstinline$static$\use{static} defines an incomplete type\index{incomplete types}. If a translation3679 unit\index{translation unit} or block \index{block} contains one or more such declarations for an3680 identifier, it must contain exactly one definition of the identifier ( but not in an enclosed block,3681 which would define a new type known only within that block).3682 \begin{rationale}3683 Incomplete type declarations allow compact mutually-recursive types.3684 \begin{lstlisting}3685 type t1; // Incomplete type declaration.3686 type t2 = struct { t1 * p; ... };3687 type t1 = struct { t2 * p; ... };3688 \end{lstlisting}3689 Without them, mutual recursion could be handled by declaring mutually recursive structures, then3690 initializing the types to those structures.3691 \begin{lstlisting}3692 struct s1;3693 type t2 = struct s2 { struct s1 * p; ... };3694 type t1 = struct s1 { struct s2 * p; ... };3695 \end{lstlisting}3696 This introduces extra names, and may force the programmer to cast between the types and their3697 implementations.3698 \end{rationale}3699 3700 A type declaration without an initializer and with storage-class specifier \index{storage-class3701 specifiers} \lstinline$extern$\use{extern} is an \define{opaque type declaration}. Opaque types3702 are object types\index{object types}. An opaque type is not a \nonterm{constant-expression};3703 neither is a structure or union that has a member whose type is not a \nonterm{constant-expression}.3704 Every other object type\index{object types} is a \nonterm{constant-expression}. Objects with static3705 storage duration shall be declared with a type that is a \nonterm{constant-expression}.3706 \begin{rationale}3707 Type declarations can declare identifiers with external linkage, whereas typedef declarations3708 declare identifiers that only exist within a translation unit. These opaque types can be used in3709 declarations, but the implementation of the type is not visible.3710 3711 Static objects can not have opaque types because space for them would have to be allocated at3712 program start-up. This is a deficiency\index{deficiencies!static opaque objects}, but I don't want3713 to deal with ``module initialization'' code just now.3714 \end{rationale}3715 3716 An incomplete type\index{incomplete types} which is not a qualified version\index{qualified type} of3717 a type is a value of type-class\index{type-class} \lstinline$dtype$. An object type\index{object3718 types} which is not a qualified version of a type is a value of type-classes \lstinline$type$ and3719 \lstinline$dtype$. A function type\index{function types} is a value of type-class3720 \lstinline$ftype$.3721 \begin{rationale}3722 Syntactically, a type value is a \nonterm{type-name}, which is a declaration for an object which3723 omits the identifier being declared.3724 3725 Object types are precisely the types that can be instantiated. Type qualifiers are not included in3726 type values because the compiler needs the information they provide at compile time to detect3727 illegal statements or to produce efficient machine instructions. For instance, the code that a3728 compiler must generate to manipulate an object that has volatile-qualified type may be different3729 from the code to manipulate an ordinary object.3730 3731 Type qualifiers are a weak point of C's type system. Consider the standard library function3732 \lstinline$strchr()$ which, given a string and a character, returns a pointer to the first3733 occurrence of the character in the string.3734 \begin{lstlisting}3735 char *strchr( const char *s, int c ) {@\impl{strchr}@3736 char real_c = c; // done because c was declared as int.3737 for ( ; *s != real_c; s++ )3738 if ( *s == '\0' ) return NULL;3739 return ( char * )s;3740 }3741 \end{lstlisting}3742 The parameter \lstinline$s$ must be \lstinline$const char *$, because \lstinline$strchr()$ might be3743 used to search a constant string, but the return type must be \lstinline$char *$, because the result3744 might be used to modify a non-constant string. Hence the body must perform a cast, and ( even worse)3745 \lstinline$strchr()$ provides a type-safe way to attempt to modify constant strings. What is needed3746 is some way to say that \lstinline$s$'s type might contain qualifiers, and the result type has3747 exactly the same qualifiers. Polymorphic functions do not provide a fix for this3748 deficiency\index{deficiencies!pointers to qualified types}, because type qualifiers are not part of3749 type values. Instead, overloading can be used to define \lstinline$strchr()$ for each combination3750 of qualifiers.3751 \end{rationale}3752 3753 \begin{rationale}3754 Since incomplete types\index{incomplete types} are not type values, they can not be used as the3755 initializer in a type declaration, or as the type of a structure or union member. This prevents the3756 declaration of types that contain each other.3757 \begin{lstlisting}3758 type t1;3759 type t2 = t1; // illegal: incomplete type t1.3760 type t1 = t2;3761 \end{lstlisting}3762 3763 The initializer in a file-scope declaration must be a constant expression. This means type3764 declarations can not build on opaque types, which is a deficiency\index{deficiencies!nesting opaque3765 types}.3766 \begin{lstlisting}3767 extern type Huge; // extended-precision integer type.3768 type Rational = struct {3769 Huge numerator, denominator; // illegal3770 };3771 struct Pair {3772 Huge first, second; // legal3773 };3774 \end{lstlisting}3775 Without this restriction, \CFA might require ``module initialization'' code ( since3776 \lstinline$Rational$ has external linkage, it must be created before any other translation unit3777 instantiates it), and would force an ordering on the initialization of the translation unit that3778 defines \lstinline$Huge$ and the translation that declares \lstinline$Rational$.3779 3780 A benefit of the restriction is that it prevents the declaration in separate translation units of3781 types that contain each other, which would be hard to prevent otherwise.3782 \begin{lstlisting}3783 // File a.c:3784 extern type t1;3785 type t2 = struct { t1 f1; ... } // illegal3786 // File b.c:3787 extern type t2;3788 type t1 = struct { t2 f2; ... } // illegal3789 \end{lstlisting}3790 \end{rationale}3791 3792 \begin{rationale}3793 Since a \nonterm{type-declaration} is a \nonterm{declaration} and not a3794 \nonterm{struct-declaration}, type declarations can not be structure members. The form of3795 \nonterm{type-declaration} forbids arrays of, pointers to, and functions returning \lstinline$type$.3796 Hence the syntax of \nonterm{type-specifier} does not have to be extended to allow type-valued3797 expressions. It also side-steps the problem of type-valued expressions producing different values3798 in different declarations.3799 3800 Since a type declaration is not a \nonterm{parameter-declaration}, functions can not have explicit3801 type parameters. This may be too restrictive, but it attempts to make compilation simpler. Recall3802 that when traditional C scanners read in an identifier, they look it up in the symbol table to3803 determine whether or not it is a typedef name, and return a ``type'' or ``identifier'' token3804 depending on what they find. A type parameter would add a type name to the current scope. The3805 scope manipulations involved in parsing the declaration of a function that takes function pointer3806 parameters and returns a function pointer may just be too complicated.3807 3808 Explicit type parameters don't seem to be very useful, anyway, because their scope would not include3809 the return type of the function. Consider the following attempt to define a type-safe memory3810 allocation function.3811 \begin{lstlisting}3812 #include <stdlib.h>3813 T * new( type T ) { return ( T * )malloc( sizeof( T) ); };3814 @\ldots@3815 int * ip = new( int );3816 \end{lstlisting}3817 This looks sensible, but \CFA's declaration-before-use rules mean that ``\lstinline$T$'' in the3818 function body refers to the parameter, but the ``\lstinline$T$'' in the return type refers to the3819 meaning of \lstinline$T$ in the scope that contains \lstinline$new$; it could be undefined, or a3820 type name, or a function or variable name. Nothing good can result from such a situation.3821 \end{rationale}3822 3823 \examples3824 Since type declarations create new types, instances of types are always passed by value.3825 \begin{lstlisting}3826 type A1 = int[2];3827 void f1( A1 a ) { a[0] = 0; };3828 typedef int A2[2];3829 void f2( A2 a ) { a[0] = 0; };3830 A1 v1;3831 A2 v2;3832 f1( v1 );3833 f2( v2 );3834 \end{lstlisting}3835 \lstinline$V1$ is passed by value, so \lstinline$f1()$'s assignment to \lstinline$a[0]$ does not3836 modify v1. \lstinline$V2$ is converted to a pointer, so \lstinline$f2()$ modifies3837 \lstinline$v2[0]$.3838 3839 A translation unit containing the declarations3840 \begin{lstlisting}3841 extern type Complex;@\use{Complex}@ // opaque type declaration.3842 extern float abs( Complex );@\use{abs}@3843 \end{lstlisting}3844 can contain declarations of complex numbers, which can be passed to \lstinline$abs$. Some other3845 translation unit must implement \lstinline$Complex$ and \lstinline$abs$. That unit might contain3846 the declarations3847 \begin{lstlisting}3848 type Complex = struct { float re, im; };@\impl{Complex}@3849 Complex cplx_i = { 0.0, 1.0 };@\impl{cplx_i}@3850 float abs( Complex c ) {@\impl{abs( Complex )}@3851 return sqrt( c.re * c.re + c.im * c.im );3852 }3853 \end{lstlisting}3854 Note that \lstinline$c$ is implicitly converted to a \lstinline$struct$ so that its components can3855 be retrieved.3856 3857 \begin{lstlisting}3858 type Time_of_day = int;@\impl{Time_of_day}@ // seconds since midnight.3859 Time_of_day ?+?( Time_of_day t1, int seconds ) {@\impl{?+?}@3860 return (( int)t1 + seconds ) % 86400;3861 }3862 \end{lstlisting}3863 \lstinline$t1$ must be cast to its implementation type to prevent infinite recursion.3864 3865 \begin{rationale}3866 Within the scope of a type definition, an instance of the type can be viewed as having that type or3867 as having the implementation type. In the \lstinline$Time_of_day$ example, the difference is3868 important. Different languages have treated the distinction between the abstraction and the3869 implementation in different ways.3870 \begin{itemize}3871 \item3872 Inside a Clu cluster \cite{clu}, the declaration of an instance states which view applies. Two3873 primitives called \lstinline$up$ and \lstinline$down$ can be used to convert between the views.3874 \item3875 The Simula class \cite{Simula87} is essentially a record type. Since the only operations on a3876 record are member selection and assignment, which can not be overloaded, there is never any3877 ambiguity as to whether the abstraction or the implementation view is being used. In {\CC}3878 \cite{c++}, operations on class instances include assignment and ``\lstinline$&$'', which can be3879 overloaded. A ``scope resolution'' operator can be used inside the class to specify whether the3880 abstract or implementation version of the operation should be used.3881 \item3882 An Ada derived type definition \cite{ada} creates a new type from an old type, and also implicitly3883 declares derived subprograms that correspond to the existing subprograms that use the old type as a3884 parameter type or result type. The derived subprograms are clones of the existing subprograms with3885 the old type replaced by the derived type. Literals and aggregates of the old type are also cloned.3886 In other words, the abstract view provides exactly the same operations as the implementation view.3887 This allows the abstract view to be used in all cases.3888 3889 The derived subprograms can be replaced by programmer-specified subprograms. This is an exception3890 to the normal scope rules, which forbid duplicate definitions of a subprogram in a scope. In this3891 case, explicit conversions between the derived type and the old type can be used.3892 \end{itemize}3893 \CFA's rules are like Clu's, except that implicit conversions and3894 conversion costs allow it to do away with most uses of \lstinline$up$ and \lstinline$down$.3895 \end{rationale}3896 3897 3898 \subsubsection{Default functions and objects}3899 3900 A declaration\index{type declaration} of a type identifier \lstinline$T$ with type-class3901 \lstinline$type$ implicitly declares a \define{default assignment} function3902 \lstinline$T ?=?( T *, T )$\use{?=?}, with the same scope\index{scopes} and linkage\index{linkage} as3903 the identifier \lstinline$T$.3904 \begin{rationale}3905 Assignment is central to C's imperative programming style, and every existing C object type has3906 assignment defined for it ( except for array types, which are treated as pointer types for purposes3907 of assignment). Without this rule, nearly every inferred type parameter would need an accompanying3908 assignment assertion parameter. If a type parameter should not have an assignment operation,3909 \lstinline$dtype$ should be used. If a type should not have assignment defined, the user can define3910 an assignment function that causes a run-time error, or provide an external declaration but no3911 definition and thus cause a link-time error.3912 \end{rationale}3913 3914 A definition\index{type definition} of a type identifier \lstinline$T$ with implementation3915 type\index{implementation type} \lstinline$I$ and type-class \lstinline$type$ implicitly defines a3916 default assignment function. A definition\index{type definition} of a type identifier \lstinline$T$3917 with implementation type \lstinline$I$ and an assertion list implicitly defines \define{default3918 functions} and \define{default objects} as declared by the assertion declarations. The default3919 objects and functions have the same scope\index{scopes} and linkage\index{linkage} as the identifier3920 \lstinline$T$. Their values are determined as follows:3921 \begin{itemize}3922 \item3923 If at the definition of \lstinline$T$ there is visible a declaration of an object with the same name3924 as the default object, and if the type of that object with all occurrence of \lstinline$I$ replaced3925 by \lstinline$T$ is compatible with the type of the default object, then the default object is3926 initialized with that object. Otherwise the scope of the declaration of \lstinline$T$ must contain3927 a definition of the default object.3928 3929 \item3930 If at the definition of \lstinline$T$ there is visible a declaration of a function with the same3931 name as the default function, and if the type of that function with all occurrence of \lstinline$I$3932 replaced by \lstinline$T$ is compatible with the type of the default function, then the default3933 function calls that function after converting its arguments and returns the converted result.3934 3935 Otherwise, if \lstinline$I$ contains exactly one anonymous member\index{anonymous member} such that3936 at the definition of \lstinline$T$ there is visible a declaration of a function with the same name3937 as the default function, and the type of that function with all occurrences of the anonymous3938 member's type in its parameter list replaced by \lstinline$T$ is compatible with the type of the3939 default function, then the default function calls that function after converting its arguments and3940 returns the result.3941 3942 Otherwise the scope of the declaration of \lstinline$T$ must contain a definition of the default3943 function.3944 \end{itemize}3945 \begin{rationale}3946 Note that a pointer to a default function will not compare as equal to a pointer to the inherited3947 function.3948 \end{rationale}3949 3950 A function or object with the same type and name as a default function or object that is declared3951 within the scope of the definition of \lstinline$T$ replaces the default function or object.3952 3953 \examples3954 \begin{lstlisting}3955 context s( type T ) {3956 T a, b;3957 }3958 struct impl { int left, right; } a = { 0, 0 };3959 type Pair | s( Pair ) = struct impl;3960 Pair b = { 1, 1 };3961 \end{lstlisting}3962 The definition of \lstinline$Pair$ implicitly defines two objects \lstinline$a$ and \lstinline$b$.3963 \lstinline$Pair a$ inherits its value from the \lstinline$struct impl a$. The definition of3964 \lstinline$Pair b$ is compulsory because there is no \lstinline$struct impl b$ to construct a value3965 from.3966 \begin{lstlisting}3967 context ss( type T ) {3968 T clone( T );3969 void munge( T * );3970 }3971 type Whatsit | ss( Whatsit );@\use{Whatsit}@3972 type Doodad | ss( Doodad ) = struct doodad {@\use{Doodad}@3973 Whatsit; // anonymous member3974 int extra;3975 };3976 Doodad clone( Doodad ) { ... }3977 \end{lstlisting}3978 The definition of \lstinline$Doodad$ implicitly defines three functions:3979 \begin{lstlisting}3980 Doodad ?=?( Doodad *, Doodad );3981 Doodad clone( Doodad );3982 void munge( Doodad * );3983 \end{lstlisting}3984 The assignment function inherits \lstinline$struct doodad$'s assignment function because the types3985 match when \lstinline$struct doodad$ is replaced by \lstinline$Doodad$ throughout.3986 \lstinline$munge()$ inherits \lstinline$Whatsit$'s \lstinline$munge()$ because the types match when3987 \lstinline$Whatsit$ is replaced by \lstinline$Doodad$ in the parameter list. \lstinline$clone()$3988 does \emph{not} inherit \lstinline$Whatsit$'s \lstinline$clone()$: replacement in the parameter3989 list yields ``\lstinline$Whatsit clone( Doodad )$'', which is not compatible with3990 \lstinline$Doodad$'s \lstinline$clone()$'s type. Hence the definition of3991 ``\lstinline$Doodad clone( Doodad )$'' is necessary.3992 3993 Default functions and objects are subject to the normal scope rules.3994 \begin{lstlisting}3995 type T = @\ldots@;3996 T a_T = @\ldots@; // Default assignment used.3997 T ?=?( T *, T );3998 T a_T = @\ldots@; // Programmer-defined assignment called.3999 \end{lstlisting}4000 \begin{rationale}4001 A compiler warning would be helpful in this situation.4002 \end{rationale}4003 4004 \begin{rationale}4005 The \emph{class} construct of object-oriented programming languages performs three independent4006 functions. It \emph{encapsulates} a data structure; it defines a \emph{subtype} relationship, whereby4007 instances of one class may be used in contexts that require instances of another; and it allows one4008 class to \emph{inherit} the implementation of another.4009 4010 In \CFA, encapsulation is provided by opaque types and the scope rules, and subtyping is provided4011 by specifications and assertions. Inheritance is provided by default functions and objects.4012 \end{rationale}4013 4014 4015 \section{Statements and blocks}4016 Many statements contain expressions, which may have more than one interpretation. The following4017 sections describe how the \CFA translator selects an interpretation. In all cases the result of4018 the selection shall be a single unambiguous interpretation\index{interpretations}.4019 4020 4021 \setcounter{subsection}{2}4022 \subsection{Expression and null statements}4023 4024 The expression in an expression statement is treated as being cast to \lstinline$void$.4025 4026 4027 \subsection{Selection statements}4028 4029 The controlling expression \lstinline$E$ in the switch statement4030 \begin{lstlisting}4031 switch ( E ) ...4032 \end{lstlisting}4033 may have more than one interpretation, but it shall have only one interpretation with an integral4034 type. An integer promotion\index{integer promotion} is performed on the expression if necessary.4035 The constant expressions in \lstinline$case$ statements with the switch are converted to the4036 promoted type.4037 4038 4039 \subsection{Iteration statements}4040 4041 The controlling expression \lstinline$E$ in the loops4042 \begin{lstlisting}4043 if ( E ) ...4044 while ( E ) ...4045 do ... while ( E );4046 \end{lstlisting}4047 is treated as ``\lstinline$( int )((E)!=0)$''.4048 4049 The statement4050 \begin{lstlisting}4051 for ( a; b; c ) @\ldots@4052 \end{lstlisting}4053 is treated as4054 \begin{lstlisting}4055 for ( ( void )( a ); ( int )(( b )!=0); ( void )( c ) ) @\ldots@4056 \end{lstlisting}4057 4058 4059 \subsection{Jump statements}4060 4061 An expression in a \lstinline$return$ statement is treated as being4062 cast to the result type of the function.4063 4064 4065 \setcounter{section}{9}4066 \section{Preprocessing directives}4067 4068 4069 \setcounter{subsection}{7}4070 \subsection{Predefined macro names}4071 4072 The implementation shall define the macro names \lstinline$__LINE__$, \lstinline$__FILE__$,4073 \lstinline$__DATE__$, and \lstinline$__TIME__$, as in the {\c11} standard. It shall not define the4074 macro name \lstinline$__STDC__$.4075 4076 In addition, the implementation shall define the macro name \lstinline$__CFORALL__$ to be the4077 decimal constant 1.4078 4079 4080 \appendix4081 4082 \chapter{Examples}4083 4084 \section{C types}4085 This section gives example specifications for some groups of types that are important in the C4086 language, in terms of the predefined operations that can be applied to those types.4087 4088 4089 \subsection{Scalar, arithmetic, and integral types}4090 4091 The pointer, integral, and floating-point types are all \define{scalar types}. All of these types4092 can be logically negated and compared. The assertion ``\lstinline$scalar( Complex )$'' should be read4093 as ``type \lstinline$Complex$ is scalar''.4094 \begin{lstlisting}4095 context scalar( type T ) {@\impl{scalar}@4096 int !?( T );4097 int ?<?( T, T ), ?<=?( T, T ), ?==?( T, T ), ?>=?( T, T ), ?>?( T, T ), ?!=?( T, T );4098 };4099 \end{lstlisting}4100 4101 The integral and floating-point types are \define{arithmetic types}, which support the basic4102 arithmetic operators. The use of an assertion in the \nonterm{spec-parameter-list} declares that,4103 in order to be arithmetic, a type must also be scalar ( and hence that scalar operations are4104 available ). This is equivalent to inheritance of specifications.4105 \begin{lstlisting}4106 context arithmetic( type T | scalar( T ) ) {@\impl{arithmetic}@@\use{scalar}@4107 T +?( T ), -?( T );4108 T ?*?( T, T ), ?/?( T, T ), ?+?( T, T ), ?-?( T, T );4109 };4110 \end{lstlisting}4111 4112 The various flavors of \lstinline$char$ and \lstinline$int$ and the enumerated types make up the4113 \define{integral types}.4114 \begin{lstlisting}4115 context integral( type T | arithmetic( T ) ) {@\impl{integral}@@\use{arithmetic}@4116 T ~?( T );4117 T ?&?( T, T ), ?|?( T, T ), ?^?( T, T );4118 T ?%?( T, T );4119 T ?<<?( T, T ), ?>>?( T, T );4120 };4121 \end{lstlisting}4122 4123 4124 \subsection{Modifiable types}4125 \index{modifiable lvalue}4126 4127 The only operation that can be applied to all modifiable lvalues is simple assignment.4128 \begin{lstlisting}4129 context m_lvalue( type T ) {@\impl{m_lvalue}@4130 T ?=?( T *, T );4131 };4132 \end{lstlisting}4133 4134 Modifiable scalar lvalues are scalars and are modifiable lvalues, and assertions in the4135 \nonterm{spec-parameter-list} reflect those relationships. This is equivalent to multiple4136 inheritance of specifications. Scalars can also be incremented and decremented.4137 \begin{lstlisting}4138 context m_l_scalar( type T | scalar( T ) | m_lvalue( T ) ) {@\impl{m_l_scalar}@4139 T ?++( T * ), ?--( T * );@\use{scalar}@@\use{m_lvalue}@4140 T ++?( T * ), --?( T * );4141 };4142 \end{lstlisting}4143 4144 Modifiable arithmetic lvalues are both modifiable scalar lvalues and arithmetic. Note that this4145 results in the ``inheritance'' of \lstinline$scalar$ along both paths.4146 \begin{lstlisting}4147 context m_l_arithmetic( type T | m_l_scalar( T ) | arithmetic( T ) ) {@\impl{m_l_arithmetic}@4148 T ?/=?( T *, T ), ?*=?( T *, T );@\use{m_l_scalar}@@\use{arithmetic}@4149 T ?+=?( T *, T ), ?-=?( T *, T );4150 };4151 4152 context m_l_integral( type T | m_l_arithmetic( T ) | integral( T ) ) {@\impl{m_l_integral}@4153 T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T );@\use{m_l_arithmetic}@4154 T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T );@\use{integral}@4155 };4156 \end{lstlisting}4157 4158 4159 \subsection{Pointer and array types}4160 4161 Array types can barely be said to exist in {\c11}, since in most cases an array name is treated as a4162 constant pointer to the first element of the array, and the subscript expression4163 ``\lstinline$a[i]$'' is equivalent to the dereferencing expression ``\lstinline$(*( a+( i )))$''.4164 Technically, pointer arithmetic and pointer comparisons other than ``\lstinline$==$'' and4165 ``\lstinline$!=$'' are only defined for pointers to array elements, but the type system does not4166 enforce those restrictions. Consequently, there is no need for a separate ``array type''4167 specification.4168 4169 Pointer types are scalar types. Like other scalar types, they have ``\lstinline$+$'' and4170 ``\lstinline$-$'' operators, but the types do not match the types of the operations in4171 \lstinline$arithmetic$, so these operators cannot be consolidated in \lstinline$scalar$.4172 \begin{lstlisting}4173 context pointer( type P | scalar( P ) ) {@\impl{pointer}@@\use{scalar}@4174 P ?+?( P, long int ), ?+?( long int, P ), ?-?( P, long int );4175 ptrdiff_t ?-?( P, P );4176 };4177 4178 context m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {@\impl{m_l_pointer}@4179 P ?+=?( P *, long int ), ?-=?( P *, long int );4180 P ?=?( P *, void * );4181 void * ?=?( void **, P );4182 };4183 \end{lstlisting}4184 4185 Specifications that define the dereference operator ( or subscript operator ) require two parameters,4186 one for the pointer type and one for the pointed-at ( or element ) type. Different specifications are4187 needed for each set of type qualifiers\index{type qualifiers}, because qualifiers are not included4188 in types. The assertion ``\lstinline$|ptr_to( Safe_pointer, int )$'' should be read as4189 ``\lstinline$Safe_pointer$ acts like a pointer to \lstinline$int$''.4190 \begin{lstlisting}4191 context ptr_to( type P | pointer( P ), type T ) {@\impl{ptr_to}@@\use{pointer}@4192 lvalue T *?( P ); lvalue T ?[?]( P, long int );4193 };4194 4195 context ptr_to_const( type P | pointer( P ), type T ) {@\impl{ptr_to_const}@4196 const lvalue T *?( P ); const lvalue T ?[?]( P, long int );@\use{pointer}@4197 };4198 4199 context ptr_to_volatile( type P | pointer( P ), type T ) }@\impl{ptr_to_volatile}@4200 volatile lvalue T *?( P ); volatile lvalue T ?[?]( P, long int );@\use{pointer}@4201 };4202 \end{lstlisting}4203 \begin{lstlisting}4204 context ptr_to_const_volatile( type P | pointer( P ), type T ) }@\impl{ptr_to_const_volatile}@4205 const volatile lvalue T *?( P );@\use{pointer}@4206 const volatile lvalue T ?[?]( P, long int );4207 };4208 \end{lstlisting}4209 4210 Assignment to pointers is more complicated than is the case with other types, because the target's4211 type can have extra type qualifiers in the pointed-at type: a ``\lstinline$T *$'' can be assigned to4212 a ``\lstinline$const T *$'', a ``\lstinline$volatile T *$'', and a ``\lstinline$const volatile T *$''.4213 Again, the pointed-at type is passed in, so that assertions can connect these specifications to the4214 ``\lstinline$ptr_to$'' specifications.4215 \begin{lstlisting}4216 context m_l_ptr_to( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to}@ type T | ptr_to( P, T )@\use{ptr_to}@ {4217 P ?=?( P *, T * );4218 T * ?=?( T **, P );4219 };4220 4221 context m_l_ptr_to_const( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_const}@ type T | ptr_to_const( P, T )@\use{ptr_to_const}@) {4222 P ?=?( P *, const T * );4223 const T * ?=?( const T **, P );4224 };4225 4226 context m_l_ptr_to_volatile( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_volatile}@ type T | ptr_to_volatile( P, T )) {@\use{ptr_to_volatile}@4227 P ?=?( P *, volatile T * );4228 volatile T * ?=?( volatile T **, P );4229 };4230 4231 context m_l_ptr_to_const_volatile( type P | ptr_to_const_volatile( P ),@\use{ptr_to_const_volatile}@@\impl{m_l_ptr_to_const_volatile}@4232 type 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}@4233 P ?=?( P *, const volatile T * );4234 const volatile T * ?=?( const volatile T **, P );4235 };4236 \end{lstlisting}4237 4238 Note the regular manner in which type qualifiers appear in those specifications. An alternative4239 specification can make use of the fact that qualification of the pointed-at type is part of a4240 pointer type to capture that regularity.4241 \begin{lstlisting}4242 context 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 ) ) {4243 MyP ?=?( MyP *, CP );4244 CP ?=?( CP *, MyP );4245 };4246 \end{lstlisting}4247 The assertion ``\lstinline$| m_l_ptr_like( Safe_ptr, const int * )$'' should be read as4248 ``\lstinline$Safe_ptr$ is a pointer type like \lstinline$const int *$''. This specification has two4249 defects, compared to the original four: there is no automatic assertion that dereferencing a4250 \lstinline$MyP$ produces an lvalue of the type that \lstinline$CP$ points at, and the4251 ``\lstinline$|m_l_pointer( CP )$'' assertion provides only a weak assurance that the argument passed4252 to \lstinline$CP$ really is a pointer type.4253 4254 4255 \section{Relationships between operations}4256 4257 Different operators often have related meanings; for instance, in C, ``\lstinline$+$'',4258 ``\lstinline$+=$'', and the two versions of ``\lstinline$++$'' perform variations of addition.4259 Languages like {\CC} and Ada allow programmers to define operators for new types, but do not4260 require that these relationships be preserved, or even that all of the operators be implemented.4261 Completeness and consistency is left to the good taste and discretion of the programmer. It is4262 possible to encourage these attributes by providing generic operator functions, or member functions4263 of abstract classes, that are defined in terms of other, related operators.4264 4265 In \CFA, polymorphic functions provide the equivalent of these generic operators, and4266 specifications explicitly define the minimal implementation that a programmer should provide. This4267 section shows a few examples.4268 4269 4270 \subsection{Relational and equality operators}4271 4272 The different comparison operators have obvious relationships, but there is no obvious subset of the4273 operations to use in the implementation of the others. However, it is usually convenient to4274 implement a single comparison function that returns a negative integer, 0, or a positive integer if4275 its first argument is respectively less than, equal to, or greater than its second argument; the4276 library function \lstinline$strcmp$ is an example.4277 4278 C and \CFA have an extra, non-obvious comparison operator: ``\lstinline$!$'', logical negation,4279 returns 1 if its operand compares equal to 0, and 0 otherwise.4280 \begin{lstlisting}4281 context comparable( type T ) {4282 const T 0;4283 int compare( T, T );4284 }4285 4286 forall( type T | comparable( T ) ) int ?<?( T l, T r ) {4287 return compare( l, r ) < 0;4288 }4289 // ... similarly for <=, ==, >=, >, and !=.4290 4291 forall( type T | comparable( T ) ) int !?( T operand ) {4292 return !compare( operand, 0 );4293 }4294 \end{lstlisting}4295 4296 4297 \subsection{Arithmetic and integer operations}4298 4299 A complete arithmetic type would provide the arithmetic operators and the corresponding assignment4300 operators. Of these, the assignment operators are more likely to be implemented directly, because4301 it is usually more efficient to alter the contents of an existing object than to create and return a4302 new one. Similarly, a complete integral type would provide integral operations based on integral4303 assignment operations.4304 \begin{lstlisting}4305 context arith_base( type T ) {4306 const T 1;4307 T ?+=?( T *, T ), ?-=?( T *, T ), ?*=?( T *, T ), ?/=?( T *, T );4308 }4309 4310 forall( type T | arith_base( T ) ) T ?+?( T l, T r ) {4311 return l += r;4312 }4313 4314 forall( type T | arith_base( T ) ) T ?++( T * operand ) {4315 T temporary = *operand;4316 *operand += 1;4317 return temporary;4318 }4319 4320 forall( type T | arith_base( T ) ) T ++?( T * operand ) {4321 return *operand += 1;4322 }4323 // ... similarly for -, --, *, and /.4324 4325 context int_base( type T ) {4326 T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T );4327 T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T );4328 }4329 4330 forall( type T | int_base( T ) ) T ?&?( T l, T r ) {4331 return l &= r;4332 }4333 // ... similarly for |, ^, %, <<, and >>.4334 \end{lstlisting}4335 4336 Note that, although an arithmetic type would certainly provide comparison functions, and an integral4337 type would provide arithmetic operations, there does not have to be any relationship among4338 \lstinline$int_base$, \lstinline$arith_base$ and \lstinline$comparable$. Note also that these4339 declarations provide guidance and assistance, but they do not define an absolutely minimal set of4340 requirements. A truly minimal implementation of an arithmetic type might only provide4341 \lstinline$0$, \lstinline$1$, and \lstinline$?-=?$, which would be used by polymorphic4342 \lstinline$?+=?$, \lstinline$?*=?$, and \lstinline$?/=?$ functions.4343 4344 Note also that \lstinline$short$ is an integer type in C11 terms, but has no operations!4345 4346 4347 \chapter{TODO}4348 Review index entries.4349 4350 Restrict allowed to qualify anything, or type/dtype parameters, but only affects pointers. This gets4351 into \lstinline$noalias$ territory. Qualifying anything (``\lstinline$short restrict rs$'') means4352 pointer parameters of \lstinline$?++$, etc, would need restrict qualifiers.4353 4354 Enumerated types. Constants are not ints. Overloading. Definition should be ``representable as an4355 integer type'', not ``as an int''. C11 usual conversions freely convert to and from ordinary4356 integer types via assignment, which works between any integer types. Does enum Color ?*?( enum4357 Color, enum Color ) really make sense? ?++ does, but it adds (int)1.4358 4359 Operators on {,signed,unsigned} char and other small types. ?<? harmless; ?*? questionable for4360 chars. Generic selections make these choices visible. Safe conversion operators? Predefined4361 ``promotion'' function?4362 4363 \lstinline$register$ assignment might be handled as assignment to a temporary with copying back and4364 forth, but copying must not be done by assignment.4365 4366 Don't use ptrdiff\_t by name in the predefineds.4367 4368 Polymorphic objects. Polymorphic typedefs and type declarations.4369 4370 4371 \bibliographystyle{plain}4372 \bibliography{refrat}4373 4374 4375 \addcontentsline{toc}{chapter}{\indexname} % add index name to table of contents4376 \begin{theindex}4377 Italic page numbers give the location of the main entry for the referenced term. Plain page numbers4378 denote uses of the indexed term. Entries for grammar non-terminals are italicized. A typewriter4379 font is used for grammar terminals and program identifiers.4380 \indexspace4381 \input{refrat.ind}4382 \end{theindex}4383 4384 \end{document}4385 4386 % Local Variables: %4387 % tab-width: 4 %4388 % fill-column: 100 %4389 % compile-command: "make" %4390 % End: % -
src/CodeGen/CodeGenerator.cc
r830c21a r353d168 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri Sep 11 12:59:09201513 // Update Count : 22 312 // Last Modified On : Wed Aug 12 14:33:52 2015 13 // Update Count : 222 14 14 // 15 15 … … 190 190 if ( designators.size() == 0 ) return; 191 191 for ( DesignatorList::iterator iter = designators.begin(); iter != designators.end(); ++iter ) { 192 if ( dynamic_cast< NameExpr * >( *iter ) ) {192 if ( NameExpr * nm = dynamic_cast< NameExpr * >( *iter ) ) { 193 193 // if expression is a name, then initializing aggregate member 194 194 output << ".";
Note:
See TracChangeset
for help on using the changeset viewer.