Changeset eb182b0
- Timestamp:
- May 23, 2017, 9:55:37 AM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 27dde72
- Parents:
- 547e9b7 (diff), 935315d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 3 added
- 15 edited
- 7 moved
Legend:
- Unmodified
- Added
- Removed
-
doc/bibliography/cfa.bib
r547e9b7 reb182b0 862 862 } 863 863 864 @techreport{C11, 865 type = {International Standard}, 864 @manual{C11, 866 865 keywords = {ISO/IEC C 11}, 867 866 contributer = {pabuhr@plg}, 868 key = {{ISO/IEC} 9889-2011}, 869 title = {American National Standard Information technology -- Programming Languages -- {C}}, 870 institution = {International Standard Organization}, 871 address = {http://www.iso.org}, 867 author = {C11}, 868 title = {Programming Languages -- {C} {ISO/IEC} 9889:2011}, 869 edition = {3rd}, 870 publisher = {International Standard Organization}, 871 address = {\href{https://www.iso.org/standard/57853.html}{https://\-www.iso.org/\-standard/\-57853.html}}, 872 872 year = 2012, 873 873 } … … 877 877 keywords = {ISO/IEC TS 19217:2015}, 878 878 contributer = {a3moss@uwaterloo.ca}, 879 key = {{ISO/IEC} {TS} 19217},880 879 author = {Concepts}, 881 title = {Information technology -- Programming languages -- {C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} Extensions for concepts },882 institution= {International Standard Organization},883 address = { http://www.iso.org},880 title = {Information technology -- Programming languages -- {C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} Extensions for concepts {ISO/IEC} {TS} 19217:2015}, 881 publisher = {International Standard Organization}, 882 address = {\href{https://www.iso.org/standard/64031.html}{https://\-www.iso.org/\-standard/\-64031.html}}, 884 883 year = 2015 885 884 } … … 1096 1095 keywords = {ISO/IEC Cobol 14}, 1097 1096 contributer = {pabuhr@plg}, 1098 key= {Cobol14},1099 title = {Programming Languages -- {Cobol} },1097 author = {Cobol14}, 1098 title = {Programming Languages -- {Cobol} ISO/IEC 1989:2014}, 1100 1099 edition = {2nd}, 1101 organization= {International Standard ISO/IEC 1989:2014}, 1102 publisher = {International Standard Organization}, 1103 address = {http://www.iso.org}, 1100 institution = {International Standard Organization}, 1101 address = {\href{https://www.iso.org/standard/51416.html}{https://\-www.iso.org/\-standard/\-51416.html}}, 1104 1102 year = 2014, 1105 1103 } … … 2836 2834 keywords = {ISO/IEC Fortran 08}, 2837 2835 contributer = {pabuhr@plg}, 2838 key= {Fortran08},2839 title = {Programming Languages -- {Fortran} Part 1 },2840 organization= {International Standard ISO/IEC 1989:2014},2836 author = {Fortran08}, 2837 title = {Programming Languages -- {Fortran} Part 1:Base Language ISO/IEC 1539-1:2010}, 2838 edition = {3rd}, 2841 2839 publisher = {International Standard Organization}, 2842 address = { http://www.iso.org},2840 address = {\href{https://www.iso.org/standard/50459.html}{https://\-www.iso.org/\-standard/\-50459.html}}, 2843 2841 year = 2010, 2844 2842 } … … 5359 5357 } 5360 5358 5361 @manual{ ANSI14:C++,5359 @manual{C++14, 5362 5360 keywords = {ISO/IEC C++ 14}, 5363 5361 contributer = {pabuhr@plg}, 5364 key= {C++14},5365 title = {Programming Languages -- {C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} },5362 author = {C++14}, 5363 title = {Programming Languages -- {C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} ISO/IEC 14882:2014}, 5366 5364 edition = {4th}, 5367 organization= {International Standard ISO/IEC 14882:2014 (E)},5368 5365 publisher = {International Standard Organization}, 5369 address = { http://www.iso.org},5366 address = {\href{https://www.iso.org/standard/64029.html}{https://\-www.iso.org/\-standard/\-64029.html}}, 5370 5367 year = 2014, 5371 5368 } … … 5706 5703 5707 5704 @manual{Ada12, 5708 keywords = {Ada}, 5709 contributer = {pabuhr@plg}, 5710 title = {Programming languages -- {Ada}}, 5705 keywords = {ISO/IEC Ada}, 5706 contributer = {pabuhr@plg}, 5707 author = {Ada12}, 5708 title = {Programming languages -- {Ada} ISO/IEC 8652:2012}, 5711 5709 edition = {3rd}, 5712 organization= {International Standard ISO/IEC 1989:2014},5713 5710 publisher = {International Standard Organization}, 5714 address = { http://www.iso.org},5711 address = {\href{https://www.iso.org/standard/61507.html}{https://\-www.iso.org/\-standard/\-61507.html}}, 5715 5712 year = 2012, 5716 5713 } -
doc/user/pointer2.fig
r547e9b7 reb182b0 8 8 -2 9 9 1200 2 10 6 1125 2100 3525 2400 10 11 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 11 1500 1950 1950 1950 1950 2250 1500 2250 1500 1950 12 1500 2100 1950 2100 1950 2400 1500 2400 1500 2100 13 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 14 2700 2100 3150 2100 3150 2400 2700 2400 2700 2100 15 4 2 0 100 0 4 10 0.0000 2 120 270 1425 2400 104\001 16 4 2 0 100 0 4 10 0.0000 2 120 90 1425 2225 y\001 17 4 0 0 100 0 4 10 0.0000 2 120 165 2025 2300 int\001 18 4 2 0 100 0 4 10 0.0000 2 120 270 2625 2400 112\001 19 4 2 0 100 0 4 10 0.0000 2 150 180 2625 2225 p2\001 20 4 1 0 100 0 4 10 0.0000 2 120 90 1725 2300 3\001 21 4 0 0 100 0 4 10 0.0000 2 120 270 3225 2300 int *\001 22 4 1 0 100 0 4 10 0.0000 2 120 270 2925 2300 100\001 23 -6 12 24 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 13 25 1500 1500 1950 1500 1950 1800 1500 1800 1500 1500 14 26 2 1 0 1 4 7 100 -1 -1 0.000 0 0 -1 1 0 2 15 27 1 1 1.00 45.00 90.00 16 2700 1800 1950 195028 2700 1800 1950 2100 17 29 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 18 30 1 1 1.00 45.00 90.00 19 2700 1950 1950 1800 20 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 21 2700 1950 3150 1950 3150 2250 2700 2250 2700 1950 31 2700 2100 1950 1800 22 32 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 23 33 2700 1500 3150 1500 3150 1800 2700 1800 2700 1500 24 34 2 1 0 1 4 7 100 -1 -1 0.000 0 0 -1 1 0 2 25 35 1 1 1.00 45.00 90.00 26 3900 1800 3150 195036 3900 1800 3150 2100 27 37 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 28 38 3900 1500 4350 1500 4350 1800 3900 1800 3900 1500 29 4 2 0 100 0 4 10 0.0000 2 120 270 1425 2250 104\00130 39 4 2 0 100 0 4 10 0.0000 2 120 270 1425 1800 100\001 31 40 4 2 0 100 0 4 10 0.0000 2 90 90 1425 1625 x\001 32 4 2 0 100 0 4 10 0.0000 2 120 90 1425 2075 y\00133 4 0 0 100 0 4 10 0.0000 2 120 165 2025 2150 int\00134 41 4 0 0 100 0 4 10 0.0000 2 120 165 2025 1700 int\001 35 4 2 0 100 0 4 10 0.0000 2 120 270 2625 2250 112\00136 4 2 0 100 0 4 10 0.0000 2 150 180 2625 2075 p2\00137 42 4 2 0 100 0 4 10 0.0000 2 120 270 2625 1800 108\001 38 43 4 2 0 100 0 4 10 0.0000 2 150 180 2625 1625 p1\001 39 4 1 0 100 0 4 10 0.0000 2 120 90 1725 2150 3\00140 44 4 1 0 100 0 4 10 0.0000 2 120 90 1725 1700 3\001 41 4 0 0 100 0 4 10 0.0000 2 120 270 3225 2150 int *\00142 45 4 0 0 100 0 4 10 0.0000 2 120 270 3225 1700 int *\001 43 46 4 2 0 100 0 4 10 0.0000 2 120 270 3825 1800 116\001 44 47 4 2 0 100 0 4 10 0.0000 2 150 180 3825 1625 p3\001 45 4 1 0 100 0 4 10 0.0000 2 120 270 2925 2150 100\00146 48 4 1 0 100 0 4 10 0.0000 2 120 270 2925 1700 104\001 47 49 4 1 0 100 0 4 10 0.0000 2 120 270 4125 1700 112\001 -
doc/user/user.tex
r547e9b7 reb182b0 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Mon May 15 18:29:58201714 %% Update Count : 1 59813 %% Last Modified On : Sun May 21 23:36:42 2017 14 %% Update Count : 1822 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 94 94 \author{ 95 95 \huge \CFA Team \medskip \\ 96 \Large Peter A. Buhr, Richard Bilson, Thierry Delisle, \smallskip \\96 \Large Andrew Beach, Richard Bilson, Peter A. Buhr, Thierry Delisle, \smallskip \\ 97 97 \Large Glen Ditchfield, Rodolfo G. Esteves, Aaron Moss, Rob Schluntz 98 98 }% author … … 217 217 218 218 As stated, the goal of the \CFA project is to engineer modern language features into C in an evolutionary rather than revolutionary way. 219 \CC~\cite{ c++,ANSI14:C++} is an example of a similar project;219 \CC~\cite{C++14,C++} is an example of a similar project; 220 220 however, it largely extended the language, and did not address many existing problems.\footnote{% 221 221 Two important existing problems addressed were changing the type of character literals from ©int© to ©char© and enumerator from ©int© to the type of its enumerators.} … … 514 514 The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right of the base type. 515 515 In the following example, \R{red} is for the base type and \B{blue} is for the qualifiers. 516 The \CFA declarations move the qualifiers to the left of the base type, i.e.,move the blue to the left of the red, while the qualifiers have the same meaning but are ordered left to right to specify a variable's type.516 The \CFA declarations move the qualifiers to the left of the base type, \ie move the blue to the left of the red, while the qualifiers have the same meaning but are ordered left to right to specify a variable's type. 517 517 \begin{quote2} 518 518 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} … … 644 644 \end{quote2} 645 645 646 Unsupported are K\&R C declarations where the base type defaults to ©int©, if no type is specified,\footnote{ 647 At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each structure declaration and type name~\cite[\S~6.7.2(2)]{C11}} 648 \eg: 649 \begin{cfa} 650 x; §\C{// int x}§ 651 *y; §\C{// int *y}§ 652 f( p1, p2 ); §\C{// int f( int p1, int p2 );}§ 653 f( p1, p2 ) {} §\C{// int f( int p1, int p2 ) {}}§ 654 \end{cfa} 646 The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine ©sizeof©: 647 \begin{quote2} 648 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 649 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 650 \begin{cfa} 651 y = (®* int®)x; 652 i = sizeof(®[ 5 ] * int®); 653 \end{cfa} 654 & 655 \begin{cfa} 656 y = (®int *®)x; 657 i = sizeof(®int *[ 5 ]®); 658 \end{cfa} 659 \end{tabular} 660 \end{quote2} 655 661 656 662 Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration. … … 659 665 660 666 661 \section{Pointer /Reference}667 \section{Pointer/Reference} 662 668 663 669 C provides a \newterm{pointer type}; 664 670 \CFA adds a \newterm{reference type}. 665 Both types contain an \newterm{address}, which is normally a location in memory. 666 Special addresses are used to denote certain states or access co-processor memory. 667 By convention, no variable is placed at address 0, so addresses like 0, 1, 2, 3 are often used to denote no-value or other special states. 668 Often dereferencing a special state causes a \Index{memory fault}, so checking is necessary during execution. 669 If the programming language assigns addresses, a program's execution is \Index{sound}, i.e., all addresses are to valid memory locations. 670 C allows programmers to assign addresses, so there is the potential for incorrect addresses, both inside and outside of the computer address-space. 671 672 Program variables are implicit pointers to memory locations generated by the compiler and automatically dereferenced, as in: 671 These types may be derived from a object or routine type, called the \newterm{referenced type}. 672 Objects of these types contain an \newterm{address}, which is normally a location in memory, but may also address memory-mapped registers in hardware devices. 673 An integer constant expression with the value 0, or such an expression cast to type ©void *©, is called a \newterm{null-pointer constant}.\footnote{ 674 One way to conceptualize the null pointer is that no variable is placed at this address, so the null-pointer address can be used to denote an uninitialized pointer/reference object; 675 \ie the null pointer is guaranteed to compare unequal to a pointer to any object or routine.} 676 An address is \newterm{sound}, if it points to a valid memory location in scope, \ie within the program's execution-environment and has not been freed. 677 Dereferencing an \newterm{unsound} address, including the null pointer, is \Index{undefined}, often resulting in a \Index{memory fault}. 678 679 A program \newterm{object} is a region of data storage in the execution environment, the contents of which can represent values. 680 In most cases, objects are located in memory at an address, and the variable name for an object is an implicit address to the object generated by the compiler and automatically dereferenced, as in: 673 681 \begin{quote2} 674 \begin{tabular}{@{}ll l@{}}682 \begin{tabular}{@{}ll@{\hspace{2em}}l@{}} 675 683 \begin{cfa} 676 684 int x; … … 691 699 \end{quote2} 692 700 where the right example is how the compiler logically interprets the variables in the left example. 693 Since a variable name only points to one location during its lifetime, it is an \Index{immutable} \Index{pointer}; 694 hence, variables ©x© and ©y© are constant pointers in the compiler interpretation. 695 In general, variable addresses are stored in instructions instead of loaded independently, so an instruction fetch implicitly loads a variable's address. 701 Since a variable name only points to one address during its lifetime, it is an \Index{immutable} \Index{pointer}; 702 hence, the implicit type of pointer variables ©x© and ©y© are constant pointers in the compiler interpretation. 703 In general, variable addresses are stored in instructions instead of loaded from memory, and hence may not occupy storage. 704 These approaches are contrasted in the following: 696 705 \begin{quote2} 697 706 \begin{tabular}{@{}l|l@{}} 707 \multicolumn{1}{c|}{explicit variable address} & \multicolumn{1}{c}{implicit variable address} \\ 708 \hline 698 709 \begin{cfa} 699 710 lda r1,100 // load address of x 700 ld r2,(r1)// load value of x711 ld r2,(r1) // load value of x 701 712 lda r3,104 // load address of y 702 st r2,(r3)// store x into y713 st r2,(r3) // store x into y 703 714 \end{cfa} 704 715 & … … 711 722 \end{tabular} 712 723 \end{quote2} 713 Finally, the immutable nature of a variable's address and the fact that there is no storage for a variable addressmeans pointer assignment\index{pointer!assignment}\index{assignment!pointer} is impossible.714 Therefore, the expression ©x = y© only has one meaning, ©*x = *y©, i.e., manipulate values, which is why explicitly writing the dereferences is unnecessary even though it occurs implicitly as part of instruction decoding.715 716 A \Index{pointer}/\Index{reference} is a generalization of a variable name, i.e.,a mutable address that can point to more than one memory location during its lifetime.717 (Similarly, an integer variable can contain multiple integer literals during its lifetime versus an integer constant representing a single literal during its lifetime andmay not occupy storage as the literal is embedded directly into instructions.)724 Finally, the immutable nature of a variable's address and the fact that there is no storage for the variable pointer means pointer assignment\index{pointer!assignment}\index{assignment!pointer} is impossible. 725 Therefore, the expression ©x = y© has only one meaning, ©*x = *y©, \ie manipulate values, which is why explicitly writing the dereferences is unnecessary even though it occurs implicitly as part of \Index{instruction decoding}. 726 727 A \Index{pointer}/\Index{reference} object is a generalization of an object variable-name, \ie a mutable address that can point to more than one memory location during its lifetime. 728 (Similarly, an integer variable can contain multiple integer literals during its lifetime versus an integer constant representing a single literal during its lifetime, and like a variable name, may not occupy storage as the literal is embedded directly into instructions.) 718 729 Hence, a pointer occupies memory to store its current address, and the pointer's value is loaded by dereferencing, \eg: 719 730 \begin{quote2} 720 \begin{tabular}{@{}l l@{}}731 \begin{tabular}{@{}l@{\hspace{2em}}l@{}} 721 732 \begin{cfa} 722 733 int x, y, ®*® p1, ®*® p2, ®**® p3; … … 727 738 \end{cfa} 728 739 & 729 \raisebox{-0. 45\totalheight}{\input{pointer2.pstex_t}}740 \raisebox{-0.5\totalheight}{\input{pointer2.pstex_t}} 730 741 \end{tabular} 731 742 \end{quote2} 732 743 733 Notice, an address has a duality\index{address!duality}: a location in memory or the value at that location. 734 In many cases, a compiler might be able to infer the meaning: 744 Notice, an address has a \Index{duality}\index{address!duality}: a location in memory or the value at that location. 745 In many cases, a compiler might be able to infer the best meaning for these two cases. 746 For example, \Index*{Algol68}~\cite{Algol68} infers pointer dereferencing to select the best meaning for each pointer usage 735 747 \begin{cfa} 736 748 p2 = p1 + x; §\C{// compiler infers *p2 = *p1 + x;}§ 737 749 \end{cfa} 738 because adding the arbitrary integer value in ©x© to the address of ©p1© and storing the resulting address into ©p2© is an unlikely operation.739 \Index*{Algol68}~\cite{Algol68} inferences pointer dereferencing to select the best meaning for each pointer usage. 740 However, in C, the following cases are ambiguous, especially with pointer arithmetic: 741 \begin{cfa} 742 p1 = p2; §\C{// p1 = p2\ \ or\ \ *p1 = *p2}§ 743 p1 = p1 + 1; §\C{// p1 = p1 + 1\ \ or\ \ *p1 = *p1 + 1}§ 744 \end{cfa} 745 746 Most languages pick one meaning as the default and the programmer explicitly indicates the other meaning to resolve the address-duality ambiguity\index{address! ambiguity}. 747 In C, the default meaning for pointers is to manipulate the pointer's address and the pointed-to value is explicitly accessed by the dereference operator ©*©. 750 Algol68 infers the following deferencing ©*p2 = *p1 + x©, because adding the arbitrary integer value in ©x© to the address of ©p1© and storing the resulting address into ©p2© is an unlikely operation. 751 Unfortunately, automatic dereferencing does not work in all cases, and so some mechanism is necessary to fix incorrect choices. 752 753 Rather than inferring dereference, most programming languages pick one implicit dereferencing semantics, and the programmer explicitly indicates the other to resolve address-duality. 754 In C, objects of pointer type always manipulate the pointer object's address: 755 \begin{cfa} 756 p1 = p2; §\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§ 757 p2 = p1 + x; §\C{// p2 = p1 + x\ \ rather than\ \ *p1 = *p1 + x}§ 758 \end{cfa} 759 even though the assignment to ©p2© is likely incorrect, and the programmer probably meant: 748 760 \begin{cfa} 749 761 p1 = p2; §\C{// pointer address assignment}§ 750 *p1 = *p1 + 1;§\C{// pointed-to value assignment / operation}§751 \end{cfa} 752 whichworks well for situations where manipulation of addresses is the primary meaning and data is rarely accessed, such as storage management (©malloc©/©free©).762 ®*®p2 = ®*®p1 + x; §\C{// pointed-to value assignment / operation}§ 763 \end{cfa} 764 The C semantics works well for situations where manipulation of addresses is the primary meaning and data is rarely accessed, such as storage management (©malloc©/©free©). 753 765 754 766 However, in most other situations, the pointed-to value is requested more often than the pointer address. … … 762 774 \end{cfa} 763 775 764 To s witch the default meaning for an address requires a new kind of pointer, called a \newterm{reference} denoted by ©&©.776 To support this common case, a reference type is introduced in \CFA, denoted by ©&©, which is the opposite dereference semantics to a pointer type, making the value at the pointed-to location the implicit semantics for dereferencing (similar but not the same as \CC \Index{reference type}s). 765 777 \begin{cfa} 766 778 int x, y, ®&® r1, ®&® r2, ®&&® r3; … … 773 785 Except for auto-dereferencing by the compiler, this reference example is the same as the previous pointer example. 774 786 Hence, a reference behaves like the variable name for the current variable it is pointing-to. 775 The simplest way to understand a reference is to imagine the compiler inserting a dereference operator before the reference variable for each reference qualifier in a declaration, \eg: 776 \begin{cfa} 777 r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); 778 \end{cfa} 779 is rewritten as: 787 One way to conceptualize a reference is via a rewrite rule, where the compiler inserts a dereference operator before the reference variable for each reference qualifier in a declaration, so the previous example becomes: 780 788 \begin{cfa} 781 789 ®*®r2 = ((®*®r1 + ®*®r2) ®*® (®**®r3 - ®*®r1)) / (®**®r3 - 15); 782 790 \end{cfa} 783 When a reference operation appears beside a dereference operation, \eg ©&*©, they cancel out.\footnote{ 791 When a reference operation appears beside a dereference operation, \eg ©&*©, they cancel out. 792 However, in C, the cancellation always yields a value (\Index{rvalue}).\footnote{ 784 793 The unary ©&© operator yields the address of its operand. 785 794 If the operand has type ``type'', the result has type ``pointer to type''. 786 795 If the operand is the result of a unary ©*© operator, neither that operator nor the ©&© operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue.~\cite[\S~6.5.3.2--3]{C11}} 787 Hence, assigning to a reference requires the address of the reference variable(\Index{lvalue}):788 \begin{cfa} 789 (&®*®)r1 = &x; §\C{// (\&*) cancel giving variabler1 not variable pointed-to by r1}§796 For a \CFA reference type, the cancellation on the left-hand side of assignment leaves the reference as an address (\Index{lvalue}): 797 \begin{cfa} 798 (&®*®)r1 = &x; §\C{// (\&*) cancel giving address of r1 not variable pointed-to by r1}§ 790 799 \end{cfa} 791 800 Similarly, the address of a reference can be obtained for assignment or computation (\Index{rvalue}): 792 801 \begin{cfa} 793 (&(&®*®)®*®)r3 = &(&®*®)r2; §\C{// (\&*) cancel giving address of r2, (\&(\&*)*) cancel giving variable r3}§ 794 \end{cfa} 795 Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth, and pointer and reference values are interchangeable because both contain addresses. 802 (&(&®*®)®*®)r3 = &(&®*®)r2; §\C{// (\&*) cancel giving address of r2, (\&(\&*)*) cancel giving address of r3}§ 803 \end{cfa} 804 Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth. 805 806 Fundamentally, pointer and reference objects are functionally interchangeable because both contain addresses. 796 807 \begin{cfa} 797 808 int x, *p1 = &x, **p2 = &p1, ***p3 = &p2, … … 805 816 &&&r3 = p3; §\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§ 806 817 \end{cfa} 807 Finally, implicit dereferencing and cancellation are a static (compilation) phenomenon not a dynamic one. 808 That is, all implicit dereferencing and any cancellation is carried out prior to the start of the program, so reference performance is equivalent to pointer performance. 809 A programmer selects a pointer or reference type solely on whether the address is dereferenced frequently or infrequently, which dictates the amount of direct aid from the compiler; 810 otherwise, everything else is equal. 811 812 Interestingly, \Index*[C++]{\CC} deals with the address duality by making the pointed-to value the default, and prevent\-ing changes to the reference address, which eliminates half of the duality. 813 \Index*{Java} deals with the address duality by making address assignment the default and requiring field assignment (direct or indirect via methods), i.e., there is no builtin bit-wise or method-wise assignment, which eliminates half of the duality. 814 815 As for a pointer, a reference may have qualifiers: 818 Furthermore, both types are equally performant, as the same amount of dereferencing occurs for both types. 819 Therefore, the choice between them is based solely on whether the address is dereferenced frequently or infrequently, which dictates the amount of implicit dereferencing aid from the compiler. 820 821 As for a pointer type, a reference type may have qualifiers: 816 822 \begin{cfa} 817 823 const int cx = 5; §\C{// cannot change cx;}§ … … 819 825 ®&®cr = &cx; §\C{// can change cr}§ 820 826 cr = 7; §\C{// error, cannot change cx}§ 821 int & const rc = x; §\C{// must be initialized , \CC reference}§827 int & const rc = x; §\C{// must be initialized}§ 822 828 ®&®rc = &x; §\C{// error, cannot change rc}§ 823 const int & const crc = cx; §\C{// must be initialized , \CC reference}§829 const int & const crc = cx; §\C{// must be initialized}§ 824 830 crc = 7; §\C{// error, cannot change cx}§ 825 831 ®&®crc = &cx; §\C{// error, cannot change crc}§ 826 832 \end{cfa} 827 Hence, for type ©& const©, there is no pointer assignment, so ©&rc = &x© is disallowed, and \emph{the address value cannot be ©0© unless an arbitrary pointer is assigned to the reference}, \eg: 828 \begin{cfa} 829 int & const r = *0; §\C{// where 0 is the int * zero}§ 830 \end{cfa} 831 Otherwise, the compiler is managing the addresses for type ©& const© not the programmer, and by a programming discipline of only using references with references, address errors can be prevented. 833 Hence, for type ©& const©, there is no pointer assignment, so ©&rc = &x© is disallowed, and \emph{the address value cannot be the null pointer unless an arbitrary pointer is coerced into the reference}: 834 \begin{cfa} 835 int & const cr = *0; §\C{// where 0 is the int * zero}§ 836 \end{cfa} 837 Note, constant reference-types do not prevent addressing errors because of explicit storage-management: 838 \begin{cfa} 839 int & const cr = *malloc(); 840 cr = 5; 841 delete &cr; 842 cr = 7; §\C{// unsound pointer dereference}§ 843 \end{cfa} 844 832 845 Finally, the position of the ©const© qualifier \emph{after} the pointer/reference qualifier causes confuse for C programmers. 833 846 The ©const© qualifier cannot be moved before the pointer/reference qualifier for C style-declarations; … … 849 862 where the \CFA declaration is read left-to-right (see \VRef{s:Declarations}). 850 863 864 In contrast to \CFA reference types, \Index*[C++]{\CC{}}'s reference types are all ©const© references, preventing changes to the reference address, so only value assignment is possible, which eliminates half of the \Index{address duality}. 865 \Index*{Java}'s reference types to objects (all Java objects are on the heap) are like C pointers, which always manipulate the address, and there is no (bit-wise) object assignment, so objects are explicitly cloned by shallow or deep copying, which eliminates half of the address duality. 866 851 867 \Index{Initialization} is different than \Index{assignment} because initialization occurs on the empty (uninitialized) storage on an object, while assignment occurs on possibly initialized storage of an object. 852 868 There are three initialization contexts in \CFA: declaration initialization, argument/parameter binding, return/temporary binding. 853 For reference initialization (like pointer), the initializing value must be an address (\Index{lvalue}) not a value (\Index{rvalue}). 854 \begin{cfa} 855 int * p = &x; §\C{// both \&x and x are possible interpretations}§ 856 int & r = x; §\C{// x unlikely interpretation, because of auto-dereferencing}§ 857 \end{cfa} 858 Hence, the compiler implicitly inserts a reference operator, ©&©, before the initialization expression. 859 Similarly, when a reference is used for a parameter/return type, the call-site argument does not require a reference operator. 860 \begin{cfa} 861 int & f( int & rp ); §\C{// reference parameter and return}§ 869 Because the object being initialized has no value, there is only one meaningful semantics with respect to address duality: it must mean address as there is no pointed-to value. 870 In contrast, the left-hand side of assignment has an address that has a duality. 871 Therefore, for pointer/reference initialization, the initializing value must be an address (\Index{lvalue}) not a value (\Index{rvalue}). 872 \begin{cfa} 873 int * p = &x; §\C{// must have address of x}§ 874 int & r = x; §\C{// must have address of x}§ 875 \end{cfa} 876 Therefore, it is superfluous to require explicitly taking the address of the initialization object, even though the type is incorrect. 877 Hence, \CFA allows ©r© to be assigned ©x© because it infers a reference for ©x©, by implicitly inserting a address-of operator, ©&©, and it is an error to put an ©&© because the types no longer match. 878 Unfortunately, C allows ©p© to be assigned with ©&x© or ©x©, by value, but most compilers warn about the latter assignment as being potentially incorrect. 879 (\CFA extends pointer initialization so a variable name is automatically referenced, eliminating the unsafe assignment.) 880 Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason. 881 \begin{cfa} 882 int & f( int & r ); §\C{// reference parameter and return}§ 862 883 z = f( x ) + f( y ); §\C{// reference operator added, temporaries needed for call results}§ 863 884 \end{cfa} 864 Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©rp© can be locally reassigned within ©f©. 865 Since ©?+?© takes its arguments by value, the references returned from ©f© are used to initialize compiler generated temporaries with value semantics that copy from the references. 885 Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©. 886 Since operator routine ©?+?© takes its arguments by value, the references returned from ©f© are used to initialize compiler generated temporaries with value semantics that copy from the references. 887 \begin{cfa} 888 int temp1 = f( x ), temp2 = f( y ); 889 z = temp1 + temp2; 890 \end{cfa} 891 This implicit referencing is crucial for reducing the syntactic burden for programmers when using references; 892 otherwise references have the same syntactic burden as pointers in these contexts. 866 893 867 894 When a pointer/reference parameter has a ©const© value (immutable), it is possible to pass literals and expressions. 868 895 \begin{cfa} 869 void f( ®const® int & cr p);870 void g( ®const® int * cp p);896 void f( ®const® int & cr ); 897 void g( ®const® int * cp ); 871 898 f( 3 ); g( &3 ); 872 899 f( x + y ); g( &(x + y) ); 873 900 \end{cfa} 874 901 Here, the compiler passes the address to the literal 3 or the temporary for the expression ©x + y©, knowing the argument cannot be changed through the parameter. 875 (The ©&© is necessary for the pointer parameter to make the types match, and is a common requirement for a C programmer.) 876 \CFA \emph{extends} this semantics to a mutable pointer/reference parameter, and the compiler implicitly creates the necessary temporary (copying the argument), which is subsequently pointed-to by the reference parameter and can be changed. 877 \begin{cfa} 878 void f( int & rp ); 879 void g( int * pp ); 902 (The ©&© is necessary for the pointer-type parameter to make the types match, and is a common requirement for a C programmer.) 903 \CFA \emph{extends} this semantics to a mutable pointer/reference parameter, and the compiler implicitly creates the necessary temporary (copying the argument), which is subsequently pointed-to by the reference parameter and can be changed.\footnote{ 904 If whole program analysis is possible, and shows the parameter is not assigned, \ie it is ©const©, the temporary is unnecessary.} 905 \begin{cfa} 906 void f( int & r ); 907 void g( int * p ); 880 908 f( 3 ); g( &3 ); §\C{// compiler implicit generates temporaries}§ 881 909 f( x + y ); g( &(x + y) ); §\C{// compiler implicit generates temporaries}§ … … 885 913 The implicit conversion allows seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call. 886 914 887 While \CFA attempts to handle pointers and references in a uniform, symmetric manner, C handles routine variables in an inconsistent way: a routine variable is both a pointer and a reference (particle and wave). 888 \begin{cfa} 889 void f( int p ) {...} 890 void (*fp)( int ) = &f; §\C{// pointer initialization}§ 891 void (*fp)( int ) = f; §\C{// reference initialization}§ 915 %\CFA attempts to handle pointers and references in a uniform, symmetric manner. 916 However, C handles routine objects in an inconsistent way. 917 A routine object is both a pointer and a reference (particle and wave). 918 \begin{cfa} 919 void f( int i ); 920 void (*fp)( int ); 921 fp = f; §\C{// reference initialization}§ 922 fp = &f; §\C{// pointer initialization}§ 923 fp = *f; §\C{// reference initialization}§ 924 fp(3); §\C{// reference invocation}§ 892 925 (*fp)(3); §\C{// pointer invocation}§ 893 fp(3); §\C{// reference invocation}§ 894 \end{cfa} 895 A routine variable is best described by a ©const© reference: 896 \begin{cfa} 897 const void (&fp)( int ) = f; 898 fp( 3 ); 899 f p = ... §\C{// error, cannot change code}§900 &fp = ...; §\C{// changing routine reference}§901 \end{cfa} 902 because the value of the routine variable is a routine literal, i.e.,the routine code is normally immutable during execution.\footnote{926 \end{cfa} 927 A routine object is best described by a ©const© reference: 928 \begin{cfa} 929 const void (&fr)( int ) = f; 930 fr = ... §\C{// error, cannot change code}§ 931 &fr = ...; §\C{// changing routine reference}§ 932 fr( 3 ); §\C{// reference call to f}§ 933 (*fr)(3); §\C{// error, incorrect type}§ 934 \end{cfa} 935 because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{ 903 936 Dynamic code rewriting is possible but only in special circumstances.} 904 \CFA allows this additional use of references for routine variables in an attempt to give a more consistent meaning for them. 905 906 907 \section{Type Operators} 908 909 The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine ©sizeof©: 910 \begin{quote2} 911 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 912 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 913 \begin{cfa} 914 y = (®* int®)x; 915 i = sizeof(®[ 5 ] * int®); 916 \end{cfa} 917 & 918 \begin{cfa} 919 y = (®int *®)x; 920 i = sizeof(®int *[ 5 ]®); 921 \end{cfa} 922 \end{tabular} 923 \end{quote2} 937 \CFA allows this additional use of references for routine objects in an attempt to give a more consistent meaning for them. 938 939 This situation is different from inferring with reference type being used ... 940 941 942 943 \begin{comment} 944 \section{References} 945 946 By introducing references in parameter types, users are given an easy way to pass a value by reference, without the need for NULL pointer checks. 947 In structures, a reference can replace a pointer to an object that should always have a valid value. 948 When a structure contains a reference, all of its constructors must initialize the reference and all instances of this structure must initialize it upon definition. 949 950 The syntax for using references in \CFA is the same as \CC with the exception of reference initialization. 951 Use ©&© to specify a reference, and access references just like regular objects, not like pointers (use dot notation to access fields). 952 When initializing a reference, \CFA uses a different syntax which differentiates reference initialization from assignment to a reference. 953 The ©&© is used on both sides of the expression to clarify that the address of the reference is being set to the address of the variable to which it refers. 954 955 956 From: Richard Bilson <rcbilson@gmail.com> 957 Date: Wed, 13 Jul 2016 01:58:58 +0000 958 Subject: Re: pointers / references 959 To: "Peter A. Buhr" <pabuhr@plg2.cs.uwaterloo.ca> 960 961 As a general comment I would say that I found the section confusing, as you move back and forth 962 between various real and imagined programming languages. If it were me I would rewrite into two 963 subsections, one that specifies precisely the syntax and semantics of reference variables and 964 another that provides the rationale. 965 966 I don't see any obvious problems with the syntax or semantics so far as I understand them. It's not 967 obvious that the description you're giving is complete, but I'm sure you'll find the special cases 968 as you do the implementation. 969 970 My big gripes are mostly that you're not being as precise as you need to be in your terminology, and 971 that you say a few things that aren't actually true even though I generally know what you mean. 972 973 20 C provides a pointer type; CFA adds a reference type. Both types contain an address, which is normally a 974 21 location in memory. 975 976 An address is not a location in memory; an address refers to a location in memory. Furthermore it 977 seems weird to me to say that a type "contains" an address; rather, objects of that type do. 978 979 21 Special addresses are used to denote certain states or access co-processor memory. By 980 22 convention, no variable is placed at address 0, so addresses like 0, 1, 2, 3 are often used to denote no-value 981 23 or other special states. 982 983 This isn't standard C at all. There has to be one null pointer representation, but it doesn't have 984 to be a literal zero representation and there doesn't have to be more than one such representation. 985 986 23 Often dereferencing a special state causes a memory fault, so checking is necessary 987 24 during execution. 988 989 I don't see the connection between the two clauses here. I feel like if a bad pointer will not cause 990 a memory fault then I need to do more checking, not less. 991 992 24 If the programming language assigns addresses, a program's execution is sound, \ie all 993 25 addresses are to valid memory locations. 994 995 You haven't said what it means to "assign" an address, but if I use my intuitive understanding of 996 the term I don't see how this can be true unless you're assuming automatic storage management. 997 998 1 Program variables are implicit pointers to memory locations generated by the compiler and automatically 999 2 dereferenced, as in: 1000 1001 There is no reason why a variable needs to have a location in memory, and indeed in a typical 1002 program many variables will not. In standard terminology an object identifier refers to data in the 1003 execution environment, but not necessarily in memory. 1004 1005 13 A pointer/reference is a generalization of a variable name, \ie a mutable address that can point to more 1006 14 than one memory location during its lifetime. 1007 1008 I feel like you're off the reservation here. In my world there are objects of pointer type, which 1009 seem to be what you're describing here, but also pointer values, which can be stored in an object of 1010 pointer type but don't necessarily have to be. For example, how would you describe the value denoted 1011 by "&main" in a C program? I would call it a (function) pointer, but that doesn't satisfy your 1012 definition. 1013 1014 16 not occupy storage as the literal is embedded directly into instructions.) Hence, a pointer occupies memory 1015 17 to store its current address, and the pointer's value is loaded by dereferencing, e.g.: 1016 1017 As with my general objection regarding your definition of variables, there is no reason why a 1018 pointer variable (object of pointer type) needs to occupy memory. 1019 1020 21 p2 = p1 + x; // compiler infers *p2 = *p1 + x; 1021 1022 What language are we in now? 1023 1024 24 pointer usage. However, in C, the following cases are ambiguous, especially with pointer arithmetic: 1025 25 p1 = p2; // p1 = p2 or *p1 = *p2 1026 1027 This isn't ambiguous. it's defined to be the first option. 1028 1029 26 p1 = p1 + 1; // p1 = p1 + 1 or *p1 = *p1 + 1 1030 1031 Again, this statement is not ambiguous. 1032 1033 13 example. Hence, a reference behaves like the variable name for the current variable it is pointing-to. The 1034 14 simplest way to understand a reference is to imagine the compiler inserting a dereference operator before 1035 15 the reference variable for each reference qualifier in a declaration, e.g.: 1036 1037 It's hard for me to understand who the audience for this part is. I think a practical programmer is 1038 likely to be satisfied with "a reference behaves like the variable name for the current variable it 1039 is pointing-to," maybe with some examples. Your "simplest way" doesn't strike me as simpler than 1040 that. It feels like you're trying to provide a more precise definition for the semantics of 1041 references, but it isn't actually precise enough to be a formal specification. If you want to 1042 express the semantics of references using rewrite rules that's a great way to do it, but lay the 1043 rules out clearly, and when you're showing an example of rewriting keep your 1044 references/pointers/values separate (right now, you use \eg "r3" to mean a reference, a pointer, 1045 and a value). 1046 1047 24 Cancellation works to arbitrary depth, and pointer and reference values are interchangeable because both 1048 25 contain addresses. 1049 1050 Except they're not interchangeable, because they have different and incompatible types. 1051 1052 40 Interestingly, C++ deals with the address duality by making the pointed-to value the default, and prevent- 1053 41 ing changes to the reference address, which eliminates half of the duality. Java deals with the address duality 1054 42 by making address assignment the default and requiring field assignment (direct or indirect via methods), 1055 43 \ie there is no builtin bit-wise or method-wise assignment, which eliminates half of the duality. 1056 1057 I can follow this but I think that's mostly because I already understand what you're trying to 1058 say. I don't think I've ever heard the term "method-wise assignment" and I don't see you defining 1059 it. Furthermore Java does have value assignment of basic (non-class) types, so your summary here 1060 feels incomplete. (If it were me I'd drop this paragraph rather than try to save it.) 1061 1062 11 Hence, for type & const, there is no pointer assignment, so &rc = &x is disallowed, and the address value 1063 12 cannot be 0 unless an arbitrary pointer is assigned to the reference. 1064 1065 Given the pains you've taken to motivate every little bit of the semantics up until now, this last 1066 clause ("the address value cannot be 0") comes out of the blue. It seems like you could have 1067 perfectly reasonable semantics that allowed the initialization of null references. 1068 1069 12 In effect, the compiler is managing the 1070 13 addresses for type & const not the programmer, and by a programming discipline of only using references 1071 14 with references, address errors can be prevented. 1072 1073 Again, is this assuming automatic storage management? 1074 1075 18 rary binding. For reference initialization (like pointer), the initializing value must be an address (lvalue) not 1076 19 a value (rvalue). 1077 1078 This sentence appears to suggest that an address and an lvalue are the same thing. 1079 1080 20 int * p = &x; // both &x and x are possible interpretations 1081 1082 Are you saying that we should be considering "x" as a possible interpretation of the initializer 1083 "&x"? It seems to me that this expression has only one legitimate interpretation in context. 1084 1085 21 int & r = x; // x unlikely interpretation, because of auto-dereferencing 1086 1087 You mean, we can initialize a reference using an integer value? Surely we would need some sort of 1088 cast to induce that interpretation, no? 1089 1090 22 Hence, the compiler implicitly inserts a reference operator, &, before the initialization expression. 1091 1092 But then the expression would have pointer type, which wouldn't be compatible with the type of r. 1093 1094 22 Similarly, 1095 23 when a reference is used for a parameter/return type, the call-site argument does not require a reference 1096 24 operator. 1097 1098 Furthermore, it would not be correct to use a reference operator. 1099 1100 45 The implicit conversion allows 1101 1 seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call. 1102 2 While C' attempts to handle pointers and references in a uniform, symmetric manner, C handles routine 1103 3 variables in an inconsistent way: a routine variable is both a pointer and a reference (particle and wave). 1104 1105 After all this talk of how expressions can have both pointer and value interpretations, you're 1106 disparaging C because it has expressions that have both pointer and value interpretations? 1107 1108 On Sat, Jul 9, 2016 at 4:18 PM Peter A. Buhr <pabuhr@plg.uwaterloo.ca> wrote: 1109 > Aaron discovered a few places where "&"s are missing and where there are too many "&", which are 1110 > corrected in the attached updated. None of the text has changed, if you have started reading 1111 > already. 1112 \end{comment} 924 1113 925 1114 … … 1348 1537 int main() { 1349 1538 * [int](int) fp = foo(); §\C{// int (*fp)(int)}§ 1350 1539 sout | fp( 3 ) | endl; 1351 1540 } 1352 1541 \end{cfa} 1353 1542 because 1354 1543 1355 Currently, there are no \Index{lambda} expressions, i.e.,unnamed routines because routine names are very important to properly select the correct routine.1356 1357 1358 \section{ Lexical List}1544 Currently, there are no \Index{lambda} expressions, \ie unnamed routines because routine names are very important to properly select the correct routine. 1545 1546 1547 \section{Tuples} 1359 1548 1360 1549 In C and \CFA, lists of elements appear in several contexts, such as the parameter list for a routine call. … … 1373 1562 [ v+w, x*y, 3.14159, f() ] 1374 1563 \end{cfa} 1375 Tuples are permitted to contain sub-tuples ( i.e.,nesting), such as ©[ [ 14, 21 ], 9 ]©, which is a 2-element tuple whose first element is itself a tuple.1564 Tuples are permitted to contain sub-tuples (\ie nesting), such as ©[ [ 14, 21 ], 9 ]©, which is a 2-element tuple whose first element is itself a tuple. 1376 1565 Note, a tuple is not a record (structure); 1377 1566 a record denotes a single value with substructure, whereas a tuple is multiple values with no substructure (see flattening coercion in Section 12.1). … … 1429 1618 tuple does not have structure like a record; a tuple is simply converted into a list of components. 1430 1619 \begin{rationale} 1431 The present implementation of \CFA does not support nested routine calls when the inner routine returns multiple values; i.e.,a statement such as ©g( f() )© is not supported.1620 The present implementation of \CFA does not support nested routine calls when the inner routine returns multiple values; \ie a statement such as ©g( f() )© is not supported. 1432 1621 Using a temporary variable to store the results of the inner routine and then passing this variable to the outer routine works, however. 1433 1622 \end{rationale} … … 1442 1631 This requirement is the same as for comma expressions in argument lists. 1443 1632 1444 Type qualifiers, i.e.,const and volatile, may modify a tuple type.1445 The meaning is the same as for a type qualifier modifying an aggregate type [Int99, x 6.5.2.3(7),x 6.7.3(11)], i.e.,the qualifier is distributed across all of the types in the tuple, \eg:1633 Type qualifiers, \ie const and volatile, may modify a tuple type. 1634 The meaning is the same as for a type qualifier modifying an aggregate type [Int99, x 6.5.2.3(7),x 6.7.3(11)], \ie the qualifier is distributed across all of the types in the tuple, \eg: 1446 1635 \begin{cfa} 1447 1636 const volatile [ int, float, const int ] x; … … 1481 1670 ©w© is implicitly opened to yield a tuple of four values, which are then assigned individually. 1482 1671 1483 A \newterm{flattening coercion} coerces a nested tuple, i.e.,a tuple with one or more components, which are themselves tuples, into a flattened tuple, which is a tuple whose components are not tuples, as in:1672 A \newterm{flattening coercion} coerces a nested tuple, \ie a tuple with one or more components, which are themselves tuples, into a flattened tuple, which is a tuple whose components are not tuples, as in: 1484 1673 \begin{cfa} 1485 1674 [ a, b, c, d ] = [ 1, [ 2, 3 ], 4 ]; … … 1516 1705 \end{cfa} 1517 1706 \index{lvalue} 1518 The left-hand side is a tuple of \emph{lvalues}, which is a list of expressions each yielding an address, i.e.,any data object that can appear on the left-hand side of a conventional assignment statement.1707 The left-hand side is a tuple of \emph{lvalues}, which is a list of expressions each yielding an address, \ie any data object that can appear on the left-hand side of a conventional assignment statement. 1519 1708 ©$\emph{expr}$© is any standard arithmetic expression. 1520 1709 Clearly, the types of the entities being assigned must be type compatible with the value of the expression. … … 1604 1793 [ x1, y1 ] = z = 0; 1605 1794 \end{cfa} 1606 As in C, the rightmost assignment is performed first, i.e.,assignment parses right to left.1795 As in C, the rightmost assignment is performed first, \ie assignment parses right to left. 1607 1796 1608 1797 … … 1669 1858 1670 1859 1671 \section{Labelled Continue /Break}1860 \section{Labelled Continue/Break} 1672 1861 1673 1862 While C provides ©continue© and ©break© statements for altering control flow, both are restricted to one level of nesting for a particular control structure. … … 1766 1955 With ©goto©, the label is at the end of the control structure, which fails to convey this important clue early enough to the reader. 1767 1956 Finally, using an explicit target for the transfer instead of an implicit target allows new constructs to be added or removed without affecting existing constructs. 1768 The implicit targets of the current ©continue© and ©break©, i.e.,the closest enclosing loop or ©switch©, change as certain constructs are added or removed.1957 The implicit targets of the current ©continue© and ©break©, \ie the closest enclosing loop or ©switch©, change as certain constructs are added or removed. 1769 1958 1770 1959 … … 1903 2092 Furthermore, any statements before the first ©case© clause can only be executed if labelled and transferred to using a ©goto©, either from outside or inside of the ©switch©, both of which are problematic. 1904 2093 As well, the declaration of ©z© cannot occur after the ©case© because a label can only be attached to a statement, and without a fall through to case 3, ©z© is uninitialized. 1905 The key observation is that the ©switch© statement branches into control structure, i.e.,there are multiple entry points into its statement body.2094 The key observation is that the ©switch© statement branches into control structure, \ie there are multiple entry points into its statement body. 1906 2095 \end{enumerate} 1907 2096 … … 1911 2100 the number of ©switch© statements is small, 1912 2101 \item 1913 most ©switch© statements are well formed ( i.e.,no \Index*{Duff's device}),2102 most ©switch© statements are well formed (\ie no \Index*{Duff's device}), 1914 2103 \item 1915 2104 the ©default© clause is usually written as the last case-clause, … … 1921 2110 \item 1922 2111 Eliminating default fall-through has the greatest potential for affecting existing code. 1923 However, even if fall-through is removed, most ©switch© statements would continue to work because of the explicit transfers already present at the end of each ©case© clause, the common placement of the ©default© clause at the end of the case list, and the most common use of fall-through, i.e.,a list of ©case© clauses executing common code, \eg:2112 However, even if fall-through is removed, most ©switch© statements would continue to work because of the explicit transfers already present at the end of each ©case© clause, the common placement of the ©default© clause at the end of the case list, and the most common use of fall-through, \ie a list of ©case© clauses executing common code, \eg: 1924 2113 \begin{cfa} 1925 2114 case 1: case 2: case 3: ... … … 1964 2153 ®int j = 0;® §\C{// disallowed}§ 1965 2154 case 1: 1966 2155 { 1967 2156 ®int k = 0;® §\C{// allowed at different nesting levels}§ 1968 2157 ... … … 2173 2362 2174 2363 The following \CC-style \Index{manipulator}s allow control over implicit seperation. 2175 Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, i.e.,the seperator is adjusted only with respect to the next printed item.2364 Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, \ie the seperator is adjusted only with respect to the next printed item. 2176 2365 \begin{cfa}[mathescape=off,belowskip=0pt] 2177 2366 sout | sepOn | 1 | 2 | 3 | sepOn | endl; §\C{// separator at start of line}§ … … 2186 2375 12 3 2187 2376 \end{cfa} 2188 Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, i.e.,the seperator is adjusted with respect to all subsequent printed items, unless locally adjusted.2377 Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items, unless locally adjusted. 2189 2378 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt] 2190 2379 sout | sepDisable | 1 | 2 | 3 | endl; §\C{// globally turn off implicit separation}§ … … 2461 2650 \caption{Constructors and Destructors} 2462 2651 \end{figure} 2463 2464 2465 \begin{comment}2466 \section{References}2467 2468 2469 By introducing references in parameter types, users are given an easy way to pass a value by reference, without the need for NULL pointer checks.2470 In structures, a reference can replace a pointer to an object that should always have a valid value.2471 When a structure contains a reference, all of its constructors must initialize the reference and all instances of this structure must initialize it upon definition.2472 2473 The syntax for using references in \CFA is the same as \CC with the exception of reference initialization.2474 Use ©&© to specify a reference, and access references just like regular objects, not like pointers (use dot notation to access fields).2475 When initializing a reference, \CFA uses a different syntax which differentiates reference initialization from assignment to a reference.2476 The ©&© is used on both sides of the expression to clarify that the address of the reference is being set to the address of the variable to which it refers.2477 \end{comment}2478 2652 2479 2653 … … 4655 4829 4656 4830 4657 \section{Syntactic Anomalies} 4658 4659 There are several ambiguous cases with operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be lexed as ©*©~\R{/}~©?*?© or ©*?©~\R{/}~©*?©. 4660 Since it is common practise to put a unary operator juxtaposed to an identifier, \eg ©*i©, users will be annoyed if they cannot do this with respect to operator identifiers. 4661 Even with this special hack, there are 5 general cases that cannot be handled. 4662 The first case is for the function-call identifier ©?()©: 4663 \begin{cfa} 4664 int *§\textvisiblespace§?()(); // declaration: space required after '*' 4665 *§\textvisiblespace§?()(); // expression: space required after '*' 4666 \end{cfa} 4667 Without the space, the string ©*?()© is ambiguous without N character look ahead; 4668 it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument/parameter list. 4669 4670 The 4 remaining cases occur in expressions: 4671 \begin{cfa} 4672 i++§\textvisiblespace§?i:0; // space required before '?' 4673 i--§\textvisiblespace§?i:0; // space required before '?' 4674 i§\textvisiblespace§?++i:0; // space required after '?' 4675 i§\textvisiblespace§?--i:0; // space required after '?' 4676 \end{cfa} 4677 In the first two cases, the string ©i++?© is ambiguous, where this string can be lexed as ©i© / ©++?© or ©i++© / ©?©; 4678 it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument list. 4679 In the second two cases, the string ©?++x© is ambiguous, where this string can be lexed as ©?++© / ©x© or ©?© / y©++x©; 4680 it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument list. 4681 4682 4683 \section{Incompatible} 4684 4685 The following incompatibles exist between \CFA and C, and are similar to Annex C for \CC~\cite{ANSI14:C++}. 4686 4687 \begin{enumerate} 4688 \item 4689 \begin{description} 4690 \item[Change:] add new keywords \\ 4691 New keywords are added to \CFA (see~\VRef{s:NewKeywords}). 4692 \item[Rationale:] keywords added to implement new semantics of \CFA. 4693 \item[Effect on original feature:] change to semantics of well-defined feature. \\ 4694 Any ISO C programs using these keywords as identifiers are invalid \CFA programs. 4695 \item[Difficulty of converting:] keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism (see~\VRef{s:BackquoteIdentifiers}): 4696 \item[How widely used:] clashes among new \CFA keywords and existing identifiers are rare. 4697 \end{description} 4698 4699 \item 4700 \begin{description} 4701 \item[Change:] type of character literal ©int© to ©char© to allow more intuitive overloading: 4702 \begin{cfa} 4703 int rtn( int i ); 4704 int rtn( char c ); 4705 rtn( 'x' ); §\C{// programmer expects 2nd rtn to be called}§ 4706 \end{cfa} 4707 \item[Rationale:] it is more intuitive for the call to ©rtn© to match the second version of definition of ©rtn© rather than the first. 4708 In particular, output of ©char© variable now print a character rather than the decimal ASCII value of the character. 4709 \begin{cfa} 4710 sout | 'x' | " " | (int)'x' | endl; 4711 x 120 4712 \end{cfa} 4713 Having to cast ©'x'© to ©char© is non-intuitive. 4714 \item[Effect on original feature:] change to semantics of well-defined feature that depend on: 4715 \begin{cfa} 4716 sizeof( 'x' ) == sizeof( int ) 4717 \end{cfa} 4718 no long work the same in \CFA programs. 4719 \item[Difficulty of converting:] simple 4720 \item[How widely used:] programs that depend upon ©sizeof( 'x' )© are rare and can be changed to ©sizeof(char)©. 4721 \end{description} 4722 4723 \item 4724 \begin{description} 4725 \item[Change:] make string literals ©const©: 4726 \begin{cfa} 4727 char * p = "abc"; §\C{// valid in C, deprecated in \CFA}§ 4728 char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§ 4729 \end{cfa} 4730 The type of a string literal is changed from ©[] char© to ©const [] char©. 4731 Similarly, the type of a wide string literal is changed from ©[] wchar_t© to ©const [] wchar_t©. 4732 \item[Rationale:] This change is a safety issue: 4733 \begin{cfa} 4734 char * p = "abc"; 4735 p[0] = 'w'; §\C{// segment fault or change constant literal}§ 4736 \end{cfa} 4737 The same problem occurs when passing a string literal to a routine that changes its argument. 4738 \item[Effect on original feature:] change to semantics of well-defined feature. 4739 \item[Difficulty of converting:] simple syntactic transformation, because string literals can be converted to ©char *©. 4740 \item[How widely used:] programs that have a legitimate reason to treat string literals as pointers to potentially modifiable memory are rare. 4741 \end{description} 4742 4743 \item 4744 \begin{description} 4745 \item[Change:] remove \newterm{tentative definitions}, which only occurs at file scope: 4746 \begin{cfa} 4747 int i; §\C{// forward definition}§ 4748 int *j = ®&i®; §\C{// forward reference, valid in C, invalid in \CFA}§ 4749 int i = 0; §\C{// definition}§ 4750 \end{cfa} 4751 is valid in C, and invalid in \CFA because duplicate overloaded object definitions at the same scope level are disallowed. 4752 This change makes it impossible to define mutually referential file-local static objects, if initializers are restricted to the syntactic forms of C. For example, 4753 \begin{cfa} 4754 struct X { int i; struct X *next; }; 4755 static struct X a; §\C{// forward definition}§ 4756 static struct X b = { 0, ®&a® }; §\C{// forward reference, valid in C, invalid in \CFA}§ 4757 static struct X a = { 1, &b }; §\C{// definition}§ 4758 \end{cfa} 4759 \item[Rationale:] avoids having different initialization rules for builtin types and userdefined types. 4760 \item[Effect on original feature:] change to semantics of well-defined feature. 4761 \item[Difficulty of converting:] the initializer for one of a set of mutually-referential file-local static objects must invoke a routine call to achieve the initialization. 4762 \item[How widely used:] seldom 4763 \end{description} 4764 4765 \item 4766 \begin{description} 4767 \item[Change:] have ©struct© introduce a scope for nested types: 4768 \begin{cfa} 4769 enum ®Colour® { R, G, B, Y, C, M }; 4770 struct Person { 4771 enum ®Colour® { R, G, B }; §\C{// nested type}§ 4772 struct Face { §\C{// nested type}§ 4773 ®Colour® Eyes, Hair; §\C{// type defined outside (1 level)}§ 4774 }; 4775 ß.ß®Colour® shirt; §\C{// type defined outside (top level)}§ 4776 ®Colour® pants; §\C{// type defined same level}§ 4777 Face looks[10]; §\C{// type defined same level}§ 4778 }; 4779 ®Colour® c = R; §\C{// type/enum defined same level}§ 4780 Personß.ß®Colour® pc = Personß.ßR; §\C{// type/enum defined inside}§ 4781 Personß.ßFace pretty; §\C{// type defined inside}§ 4782 \end{cfa} 4783 In C, the name of the nested types belongs to the same scope as the name of the outermost enclosing structure, i.e., the nested types are hoisted to the scope of the outer-most type, which is not useful and confusing. 4784 \CFA is C \emph{incompatible} on this issue, and provides semantics similar to \Index*[C++]{\CC}. 4785 Nested types are not hoisted and can be referenced using the field selection operator ``©.©'', unlike the \CC scope-resolution operator ``©::©''. 4786 \item[Rationale:] ©struct© scope is crucial to \CFA as an information structuring and hiding mechanism. 4787 \item[Effect on original feature:] change to semantics of well-defined feature. 4788 \item[Difficulty of converting:] Semantic transformation. 4789 \item[How widely used:] C programs rarely have nest types because they are equivalent to the hoisted version. 4790 \end{description} 4791 4792 \item 4793 \begin{description} 4794 \item[Change:] In C++, the name of a nested class is local to its enclosing class. 4795 \item[Rationale:] C++ classes have member functions which require that classes establish scopes. 4796 \item[Difficulty of converting:] Semantic transformation. To make the struct type name visible in the scope of the enclosing struct, the struct tag could be declared in the scope of the enclosing struct, before the enclosing struct is defined. Example: 4797 \begin{cfa} 4798 struct Y; §\C{// struct Y and struct X are at the same scope}§ 4799 struct X { 4800 struct Y { /* ... */ } y; 4801 }; 4802 \end{cfa} 4803 All the definitions of C struct types enclosed in other struct definitions and accessed outside the scope of the enclosing struct could be exported to the scope of the enclosing struct. 4804 Note: this is a consequence of the difference in scope rules, which is documented in 3.3. 4805 \item[How widely used:] Seldom. 4806 \end{description} 4807 4808 \item 4809 \begin{description} 4810 \item[Change:] comma expression is disallowed as subscript 4811 \item[Rationale:] safety issue to prevent subscripting error for multidimensional arrays: ©x[i,j]© instead of ©x[i][j]©, and this syntactic form then taken by \CFA for new style arrays. 4812 \item[Effect on original feature:] change to semantics of well-defined feature. 4813 \item[Difficulty of converting:] semantic transformation of ©x[i,j]© to ©x[(i,j)]© 4814 \item[How widely used:] seldom. 4815 \end{description} 4816 \end{enumerate} 4831 \section{Syntax Ambiguities} 4832 4833 C has a number of syntax ambiguities, which are resolved by taking the longest sequence of overlapping characters that constitute a token. 4834 For example, the program fragment ©x+++++y© is parsed as \lstinline[showspaces=true]@x ++ ++ + y@ because operator tokens ©++© and ©+© overlap. 4835 Unfortunately, the longest sequence violates a constraint on increment operators, even though the parse \lstinline[showspaces=true]@x ++ + ++ y@ might yield a correct expression. 4836 Hence, C programmers are aware that spaces have to added to disambiguate certain syntactic cases. 4837 4838 In \CFA, there are ambiguous cases with dereference and operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be interpreted as: 4839 \begin{cfa} 4840 *?§\color{red}\textvisiblespace§*? §\C{// dereference operator, dereference operator}§ 4841 *§\color{red}\textvisiblespace§?*? §\C{// dereference, multiplication operator}§ 4842 \end{cfa} 4843 By default, the first interpretation is selected, which does not yield a meaningful parse. 4844 Therefore, \CFA does a lexical look-ahead for the second case, and backtracks to return the leading unary operator and reparses the trailing operator identifier. 4845 Otherwise a space is needed between the unary operator and operator identifier to disambiguate this common case. 4846 4847 A similar issue occurs with the dereference, ©*?(...)©, and routine-call, ©?()(...)© identifiers. 4848 The ambiguity occurs when the deference operator has no parameters: 4849 \begin{cfa} 4850 *?()§\color{red}\textvisiblespace...§ ; 4851 *?()§\color{red}\textvisiblespace...§(...) ; 4852 \end{cfa} 4853 requiring arbitrary whitespace look-ahead for the routine-call parameter-list to disambiguate. 4854 However, the dereference operator \emph{must} have a parameter/argument to dereference ©*?(...)©. 4855 Hence, always interpreting the string ©*?()© as \lstinline[showspaces=true]@* ?()@ does not preclude any meaningful program. 4856 4857 The remaining cases are with the increment/decrement operators and conditional expression, \eg: 4858 \begin{cfa} 4859 i++?§\color{red}\textvisiblespace...§(...); 4860 i?++§\color{red}\textvisiblespace...§(...); 4861 \end{cfa} 4862 requiring arbitrary whitespace look-ahead for the operator parameter-list, even though that interpretation is an incorrect expression (juxtaposed identifiers). 4863 Therefore, it is necessary to disambiguate these cases with a space: 4864 \begin{cfa} 4865 i++§\color{red}\textvisiblespace§? i : 0; 4866 i?§\color{red}\textvisiblespace§++i : 0; 4867 \end{cfa} 4817 4868 4818 4869 … … 4821 4872 4822 4873 \begin{quote2} 4823 \begin{tabular}{lll }4874 \begin{tabular}{llll} 4824 4875 \begin{tabular}{@{}l@{}} 4825 4876 ©_AT© \\ … … 4829 4880 ©coroutine© \\ 4830 4881 ©disable© \\ 4831 ©dtype© \\4832 ©enable© \\4833 4882 \end{tabular} 4834 4883 & 4835 4884 \begin{tabular}{@{}l@{}} 4885 ©dtype© \\ 4886 ©enable© \\ 4836 4887 ©fallthrough© \\ 4837 4888 ©fallthru© \\ 4838 4889 ©finally© \\ 4839 4890 ©forall© \\ 4891 \end{tabular} 4892 & 4893 \begin{tabular}{@{}l@{}} 4840 4894 ©ftype© \\ 4841 4895 ©lvalue© \\ 4842 4896 ©monitor© \\ 4843 4897 ©mutex© \\ 4898 ©one_t© \\ 4899 ©otype© \\ 4844 4900 \end{tabular} 4845 4901 & 4846 4902 \begin{tabular}{@{}l@{}} 4847 ©one_t© \\4848 ©otype© \\4849 4903 ©throw© \\ 4850 4904 ©throwResume© \\ … … 4856 4910 \end{tabular} 4857 4911 \end{quote2} 4912 4913 4914 \section{Incompatible} 4915 4916 The following incompatibles exist between \CFA and C, and are similar to Annex C for \CC~\cite{C++14}. 4917 4918 4919 \begin{enumerate} 4920 \item 4921 \begin{description} 4922 \item[Change:] add new keywords \\ 4923 New keywords are added to \CFA (see~\VRef{s:CFAKeywords}). 4924 \item[Rationale:] keywords added to implement new semantics of \CFA. 4925 \item[Effect on original feature:] change to semantics of well-defined feature. \\ 4926 Any ISO C programs using these keywords as identifiers are invalid \CFA programs. 4927 \item[Difficulty of converting:] keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism (see~\VRef{s:BackquoteIdentifiers}). 4928 \item[How widely used:] clashes among new \CFA keywords and existing identifiers are rare. 4929 \end{description} 4930 4931 \item 4932 \begin{description} 4933 \item[Change:] drop K\&R C declarations \\ 4934 K\&R declarations allow an implicit base-type of ©int©, if no type is specified, plus an alternate syntax for declaring parameters. 4935 \eg: 4936 \begin{cfa} 4937 x; §\C{// int x}§ 4938 *y; §\C{// int *y}§ 4939 f( p1, p2 ); §\C{// int f( int p1, int p2 );}§ 4940 g( p1, p2 ) int p1, p2; §\C{// int g( int p1, int p2 );}§ 4941 \end{cfa} 4942 \CFA supports K\&R routine definitions: 4943 \begin{cfa} 4944 f( a, b, c ) §\C{// default int return}§ 4945 int a, b; char c §\C{// K\&R parameter declarations}§ 4946 { 4947 ... 4948 } 4949 \end{cfa} 4950 \item[Rationale:] dropped from C11 standard.\footnote{ 4951 At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each structure declaration and type name~\cite[\S~6.7.2(2)]{C11}} 4952 \item[Effect on original feature:] original feature is deprecated. \\ 4953 Any old C programs using these K\&R declarations are invalid \CFA programs. 4954 \item[Difficulty of converting:] trivial to convert to \CFA. 4955 \item[How widely used:] existing usages are rare. 4956 \end{description} 4957 4958 \item 4959 \begin{description} 4960 \item[Change:] type of character literal ©int© to ©char© to allow more intuitive overloading: 4961 \begin{cfa} 4962 int rtn( int i ); 4963 int rtn( char c ); 4964 rtn( 'x' ); §\C{// programmer expects 2nd rtn to be called}§ 4965 \end{cfa} 4966 \item[Rationale:] it is more intuitive for the call to ©rtn© to match the second version of definition of ©rtn© rather than the first. 4967 In particular, output of ©char© variable now print a character rather than the decimal ASCII value of the character. 4968 \begin{cfa} 4969 sout | 'x' | " " | (int)'x' | endl; 4970 x 120 4971 \end{cfa} 4972 Having to cast ©'x'© to ©char© is non-intuitive. 4973 \item[Effect on original feature:] change to semantics of well-defined feature that depend on: 4974 \begin{cfa} 4975 sizeof( 'x' ) == sizeof( int ) 4976 \end{cfa} 4977 no long work the same in \CFA programs. 4978 \item[Difficulty of converting:] simple 4979 \item[How widely used:] programs that depend upon ©sizeof( 'x' )© are rare and can be changed to ©sizeof(char)©. 4980 \end{description} 4981 4982 \item 4983 \begin{description} 4984 \item[Change:] make string literals ©const©: 4985 \begin{cfa} 4986 char * p = "abc"; §\C{// valid in C, deprecated in \CFA}§ 4987 char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§ 4988 \end{cfa} 4989 The type of a string literal is changed from ©[] char© to ©const [] char©. 4990 Similarly, the type of a wide string literal is changed from ©[] wchar_t© to ©const [] wchar_t©. 4991 \item[Rationale:] This change is a safety issue: 4992 \begin{cfa} 4993 char * p = "abc"; 4994 p[0] = 'w'; §\C{// segment fault or change constant literal}§ 4995 \end{cfa} 4996 The same problem occurs when passing a string literal to a routine that changes its argument. 4997 \item[Effect on original feature:] change to semantics of well-defined feature. 4998 \item[Difficulty of converting:] simple syntactic transformation, because string literals can be converted to ©char *©. 4999 \item[How widely used:] programs that have a legitimate reason to treat string literals as pointers to potentially modifiable memory are rare. 5000 \end{description} 5001 5002 \item 5003 \begin{description} 5004 \item[Change:] remove \newterm{tentative definitions}, which only occurs at file scope: 5005 \begin{cfa} 5006 int i; §\C{// forward definition}§ 5007 int *j = ®&i®; §\C{// forward reference, valid in C, invalid in \CFA}§ 5008 int i = 0; §\C{// definition}§ 5009 \end{cfa} 5010 is valid in C, and invalid in \CFA because duplicate overloaded object definitions at the same scope level are disallowed. 5011 This change makes it impossible to define mutually referential file-local static objects, if initializers are restricted to the syntactic forms of C. For example, 5012 \begin{cfa} 5013 struct X { int i; struct X *next; }; 5014 static struct X a; §\C{// forward definition}§ 5015 static struct X b = { 0, ®&a® }; §\C{// forward reference, valid in C, invalid in \CFA}§ 5016 static struct X a = { 1, &b }; §\C{// definition}§ 5017 \end{cfa} 5018 \item[Rationale:] avoids having different initialization rules for builtin types and userdefined types. 5019 \item[Effect on original feature:] change to semantics of well-defined feature. 5020 \item[Difficulty of converting:] the initializer for one of a set of mutually-referential file-local static objects must invoke a routine call to achieve the initialization. 5021 \item[How widely used:] seldom 5022 \end{description} 5023 5024 \item 5025 \begin{description} 5026 \item[Change:] have ©struct© introduce a scope for nested types: 5027 \begin{cfa} 5028 enum ®Colour® { R, G, B, Y, C, M }; 5029 struct Person { 5030 enum ®Colour® { R, G, B }; §\C{// nested type}§ 5031 struct Face { §\C{// nested type}§ 5032 ®Colour® Eyes, Hair; §\C{// type defined outside (1 level)}§ 5033 }; 5034 ®.Colour® shirt; §\C{// type defined outside (top level)}§ 5035 ®Colour® pants; §\C{// type defined same level}§ 5036 Face looks[10]; §\C{// type defined same level}§ 5037 }; 5038 ®Colour® c = R; §\C{// type/enum defined same level}§ 5039 Person®.Colour® pc = Person®.®R; §\C{// type/enum defined inside}§ 5040 Person®.®Face pretty; §\C{// type defined inside}§ 5041 \end{cfa} 5042 In C, the name of the nested types belongs to the same scope as the name of the outermost enclosing structure, \ie the nested types are hoisted to the scope of the outer-most type, which is not useful and confusing. 5043 \CFA is C \emph{incompatible} on this issue, and provides semantics similar to \Index*[C++]{\CC}. 5044 Nested types are not hoisted and can be referenced using the field selection operator ``©.©'', unlike the \CC scope-resolution operator ``©::©''. 5045 \item[Rationale:] ©struct© scope is crucial to \CFA as an information structuring and hiding mechanism. 5046 \item[Effect on original feature:] change to semantics of well-defined feature. 5047 \item[Difficulty of converting:] Semantic transformation. 5048 \item[How widely used:] C programs rarely have nest types because they are equivalent to the hoisted version. 5049 \end{description} 5050 5051 \item 5052 \begin{description} 5053 \item[Change:] In C++, the name of a nested class is local to its enclosing class. 5054 \item[Rationale:] C++ classes have member functions which require that classes establish scopes. 5055 \item[Difficulty of converting:] Semantic transformation. To make the struct type name visible in the scope of the enclosing struct, the struct tag could be declared in the scope of the enclosing struct, before the enclosing struct is defined. Example: 5056 \begin{cfa} 5057 struct Y; §\C{// struct Y and struct X are at the same scope}§ 5058 struct X { 5059 struct Y { /* ... */ } y; 5060 }; 5061 \end{cfa} 5062 All the definitions of C struct types enclosed in other struct definitions and accessed outside the scope of the enclosing struct could be exported to the scope of the enclosing struct. 5063 Note: this is a consequence of the difference in scope rules, which is documented in 3.3. 5064 \item[How widely used:] Seldom. 5065 \end{description} 5066 5067 \item 5068 \begin{description} 5069 \item[Change:] comma expression is disallowed as subscript 5070 \item[Rationale:] safety issue to prevent subscripting error for multidimensional arrays: ©x[i,j]© instead of ©x[i][j]©, and this syntactic form then taken by \CFA for new style arrays. 5071 \item[Effect on original feature:] change to semantics of well-defined feature. 5072 \item[Difficulty of converting:] semantic transformation of ©x[i,j]© to ©x[(i,j)]© 5073 \item[How widely used:] seldom. 5074 \end{description} 5075 \end{enumerate} 4858 5076 4859 5077 … … 4878 5096 \end{tabular} 4879 5097 \end{quote2} 4880 For the prescribed head-files, \CFA implicitly wraps theirincludes in an ©extern "C"©;5098 For the prescribed head-files, \CFA uses header interposition to wraps these includes in an ©extern "C"©; 4881 5099 hence, names in these include files are not mangled\index{mangling!name} (see~\VRef{s:Interoperability}). 4882 5100 All other C header files must be explicitly wrapped in ©extern "C"© to prevent name mangling. … … 4886 5104 \label{s:StandardLibrary} 4887 5105 4888 The goal of the \CFA standard-library is to wrap many of the existing C library-routines that are explicitly polymorphic into implicitlypolymorphic versions.5106 The \CFA standard-library wraps many existing explicitly-polymorphic C general-routines into implicitly-polymorphic versions. 4889 5107 4890 5108 … … 4893 5111 \leavevmode 4894 5112 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 4895 forall( otype T) T * malloc( void );§\indexc{malloc}§4896 forall( otype T) T * malloc( char fill );4897 forall( otype T) T * malloc( T * ptr, size_t size );4898 forall( otype T) T * malloc( T * ptr, size_t size, unsigned char fill );4899 forall( otype T) T * calloc( size_t nmemb );§\indexc{calloc}§4900 forall( otype T) T * realloc( T * ptr, size_t size );§\indexc{ato}§4901 forall( otype T) T * realloc( T * ptr, size_t size, unsigned char fill );4902 4903 forall( otype T) T * aligned_alloc( size_t alignment );§\indexc{ato}§4904 forall( otype T) T * memalign( size_t alignment ); // deprecated4905 forall( otype T) int posix_memalign( T ** ptr, size_t alignment );5113 forall( dtype T | sized(T) ) T * malloc( void );§\indexc{malloc}§ 5114 forall( dtype T | sized(T) ) T * malloc( char fill ); 5115 forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size ); 5116 forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size, unsigned char fill ); 5117 forall( dtype T | sized(T) ) T * calloc( size_t nmemb );§\indexc{calloc}§ 5118 forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size );§\indexc{ato}§ 5119 forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size, unsigned char fill ); 5120 5121 forall( dtype T | sized(T) ) T * aligned_alloc( size_t alignment );§\indexc{ato}§ 5122 forall( dtype T | sized(T) ) T * memalign( size_t alignment ); // deprecated 5123 forall( dtype T | sized(T) ) int posix_memalign( T ** ptr, size_t alignment ); 4906 5124 4907 5125 forall( otype T ) T * memset( T * ptr, unsigned char fill ); // use default value '\0' for fill 4908 5126 forall( otype T ) T * memset( T * ptr ); // remove when default value available 5127 5128 forall( dtype T, ttype Params | sized(T) | { void ?{}(T *, Params); } ) T * new( Params p ); 5129 forall( dtype T | { void ^?{}(T *); } ) void delete( T * ptr ); 5130 forall( dtype T, ttype Params | { void ^?{}(T *); void delete(Params); } ) void delete( T * ptr, Params rest ); 4909 5131 \end{cfa} 4910 5132 … … 5010 5232 \label{s:Math Library} 5011 5233 5012 The goal of the \CFA math-library is to wrap many of the existing C math library-routines that are explicitly polymorphic into implicitlypolymorphic versions.5234 The \CFA math-library wraps many existing explicitly-polymorphic C math-routines into implicitly-polymorphic versions. 5013 5235 5014 5236 -
doc/working/exception/impl/main.c
r547e9b7 reb182b0 26 26 extern int this_exception; 27 27 _Unwind_Reason_Code foo_try_match() { 28 return this_exception == 2? _URC_HANDLER_FOUND : _URC_CONTINUE_UNWIND;28 return this_exception == 3 ? _URC_HANDLER_FOUND : _URC_CONTINUE_UNWIND; 29 29 } 30 30 -
src/CodeGen/GenType.cc
r547e9b7 reb182b0 237 237 void GenType::visit( TupleType * tupleType ) { 238 238 assertf( ! genC, "Tuple types should not reach code generation." ); 239 Visitor::visit( tupleType );240 239 unsigned int i = 0; 241 240 std::ostringstream os; … … 245 244 os << genType( t, "", pretty, genC, lineMarks ) << (i == tupleType->size() ? "" : ", "); 246 245 } 247 os << "] ";246 os << "] "; 248 247 typeString = os.str() + typeString; 249 248 } -
src/GenPoly/InstantiateGeneric.cc
r547e9b7 reb182b0 367 367 concDecl->set_body( inst->get_baseStruct()->has_body() ); 368 368 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 369 DeclMutator::addDeclaration( concDecl ); 370 insert( inst, typeSubs, concDecl ); 369 insert( inst, typeSubs, concDecl ); // must insert before recursion 371 370 concDecl->acceptMutator( *this ); // recursively instantiate members 371 DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first 372 372 } 373 373 StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() ); … … 422 422 concDecl->set_body( inst->get_baseUnion()->has_body() ); 423 423 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 424 DeclMutator::addDeclaration( concDecl ); 425 insert( inst, typeSubs, concDecl ); 424 insert( inst, typeSubs, concDecl ); // must insert before recursion 426 425 concDecl->acceptMutator( *this ); // recursively instantiate members 426 DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first 427 427 } 428 428 UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() ); -
src/InitTweak/FixInit.cc
r547e9b7 reb182b0 619 619 620 620 Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) { 621 stmtExpr = safe_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) ); 621 // function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression, 622 // since temporaries can be shared across sub-expressions, e.g. 623 // [A, A] f(); 624 // g([A] x, [A] y); 625 // f(g()); 626 // f is executed once, so the return temporary is shared across the tuple constructors for x and y. 627 std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids(); 628 for ( Statement *& stmt : stmts ) { 629 stmt = stmt->acceptMutator( *this ); 630 } // for 631 // stmtExpr = safe_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) ); 622 632 assert( stmtExpr->get_result() ); 623 633 Type * result = stmtExpr->get_result(); … … 886 896 Parent::visit( compoundStmt ); 887 897 888 // add destructors for the current scope that we're exiting 898 // add destructors for the current scope that we're exiting, unless the last statement is a return, which 899 // causes unreachable code warnings 889 900 std::list< Statement * > & statements = compoundStmt->get_kids(); 890 insertDtors( reverseDeclOrder.front().begin(), reverseDeclOrder.front().end(), back_inserter( statements ) ); 901 if ( ! statements.empty() && ! dynamic_cast< ReturnStmt * >( statements.back() ) ) { 902 insertDtors( reverseDeclOrder.front().begin(), reverseDeclOrder.front().end(), back_inserter( statements ) ); 903 } 891 904 reverseDeclOrder.pop_front(); 892 905 } -
src/Parser/ExpressionNode.cc
r547e9b7 reb182b0 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 30 17:02:46201713 // Update Count : 5 1512 // Last Modified On : Wed May 17 21:31:01 2017 13 // Update Count : 527 14 14 // 15 15 … … 207 207 } // build_field_name_fraction_constants 208 208 209 210 209 211 Expression * build_field_name_REALFRACTIONconstant( const std::string & str ) { 210 assert( str[0] == '.');212 if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str ); 211 213 Expression * ret = build_constantInteger( *new std::string( str.substr(1) ) ); 212 214 delete &str; … … 215 217 216 218 Expression * build_field_name_REALDECIMALconstant( const std::string & str ) { 217 assert( str[str.size()-1] == '.');219 if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str ); 218 220 Expression * ret = build_constantInteger( *new std::string( str.substr( 0, str.size()-1 ) ) ); 219 221 delete &str; -
src/Parser/lex.ll
r547e9b7 reb182b0 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Mon Mar 13 08:36:17201713 * Update Count : 5 0612 * Last Modified On : Thu May 18 09:03:49 2017 13 * Update Count : 513 14 14 */ 15 15 … … 77 77 // numeric constants, CFA: '_' in constant 78 78 hex_quad {hex}("_"?{hex}){3} 79 integer_suffix "_"?(([uU] [lL]?)|([uU]("ll"|"LL")?)|([lL][uU]?)|("ll"|"LL")[uU]?)79 integer_suffix "_"?(([uU](("ll"|"LL"|[lL])[iI]|[iI]?("ll"|"LL"|[lL])?))|([iI](("ll"|"LL"|[lL])[uU]|[uU]?("ll"|"LL"|[lL])?))|(("ll"|"LL"|[lL])([iI][uU]|[uU]?[iI]?))) 80 80 81 81 octal_digits ({octal})|({octal}({octal}|"_")*{octal}) … … 91 91 92 92 decimal_digits ({decimal})|({decimal}({decimal}|"_")*{decimal}) 93 real_decimal {decimal_digits}"." 94 real_fraction "."{decimal_digits} 95 real_constant {decimal_digits} ?{real_fraction}93 real_decimal {decimal_digits}"."{exponent}?{floating_suffix}? 94 real_fraction "."{decimal_digits}{exponent}?{floating_suffix}? 95 real_constant {decimal_digits}{real_fraction} 96 96 exponent "_"?[eE]"_"?[+-]?{decimal_digits} 97 // GCC: D (double), DL (long double) and iI (imaginary) suffixes 98 floating_suffix "_"?([fFdDlL][iI]?|"DL"|[iI][lLfFdD]?) 99 //floating_suffix "_"?([fFdD]|[lL]|[D][L])|([iI][lLfFdD])|([lLfFdD][iI])) 97 // GCC: D (double) and iI (imaginary) suffixes, and DL (long double) 98 floating_suffix "_"?([fFdDlL][iI]?|[iI][lLfFdD]?|"DL") 100 99 floating_constant (({real_constant}{exponent}?)|({decimal_digits}{exponent})){floating_suffix}? 101 100 -
src/Parser/parser.yy
r547e9b7 reb182b0 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Ma r 30 15:42:32201713 // Update Count : 23 1812 // Last Modified On : Thu May 18 18:06:17 2017 13 // Update Count : 2338 14 14 // 15 15 … … 85 85 } // for 86 86 } // distExt 87 88 bool forall = false; // aggregate have one or more forall qualifiers ? 87 89 %} 88 90 … … 1556 1558 sue_type_specifier: // struct, union, enum + type specifier 1557 1559 elaborated_type 1558 | type_qualifier_list elaborated_type 1559 { $$ = $2->addQualifiers( $1 ); } 1560 | type_qualifier_list 1561 { if ( $1->type != nullptr && $1->type->forall ) forall = true; } // remember generic type 1562 elaborated_type 1563 { $$ = $3->addQualifiers( $1 ); } 1560 1564 | sue_type_specifier type_qualifier 1561 1565 { $$ = $1->addQualifiers( $2 ); } … … 1613 1617 { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); } 1614 1618 | aggregate_key attribute_list_opt no_attr_identifier_or_type_name 1615 { typedefTable.makeTypedef( *$3 ); } 1619 { 1620 typedefTable.makeTypedef( *$3 ); // create typedef 1621 if ( forall ) typedefTable.changeKind( *$3, TypedefTable::TG ); // possibly update 1622 forall = false; // reset 1623 } 1616 1624 '{' field_declaration_list '}' 1617 1625 { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $6, true )->addQualifiers( $2 ); } -
src/SymTab/Validate.cc
r547e9b7 reb182b0 208 208 }; 209 209 210 /// ensure that generic types have the correct number of type arguments 211 class ValidateGenericParameters : public Visitor { 212 public: 213 typedef Visitor Parent; 214 virtual void visit( StructInstType * inst ) final override; 215 virtual void visit( UnionInstType * inst ) final override; 216 }; 217 210 218 class ArrayLength : public Visitor { 211 219 public: … … 235 243 Pass3 pass3( 0 ); 236 244 CompoundLiteral compoundliteral; 237 238 HoistStruct::hoistStruct( translationUnit ); 245 ValidateGenericParameters genericParams; 246 239 247 EliminateTypedef::eliminateTypedef( translationUnit ); 248 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order 240 249 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen 241 250 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions 251 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes 242 252 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist 243 253 VerifyCtorDtorAssign::verify( translationUnit ); // must happen before autogen, because autogen examines existing ctor/dtors … … 829 839 } 830 840 841 template< typename Aggr > 842 void validateGeneric( Aggr * inst ) { 843 std::list< TypeDecl * > * params = inst->get_baseParameters(); 844 if ( params != NULL ) { 845 std::list< Expression * > & args = inst->get_parameters(); 846 if ( args.size() < params->size() ) throw SemanticError( "Too few type arguments in generic type ", inst ); 847 if ( args.size() > params->size() ) throw SemanticError( "Too many type arguments in generic type ", inst ); 848 } 849 } 850 851 void ValidateGenericParameters::visit( StructInstType * inst ) { 852 validateGeneric( inst ); 853 Parent::visit( inst ); 854 } 855 856 void ValidateGenericParameters::visit( UnionInstType * inst ) { 857 validateGeneric( inst ); 858 Parent::visit( inst ); 859 } 860 831 861 DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) { 832 862 storageClasses = objectDecl->get_storageClasses(); -
src/SynTree/TypeSubstitution.cc
r547e9b7 reb182b0 166 166 boundVars.insert( (*tyvar )->get_name() ); 167 167 } // for 168 } // if169 // bind type variables from generic type instantiations170 std::list< TypeDecl* > *baseParameters = type->get_baseParameters();171 if ( baseParameters && ! type->get_parameters().empty()) {172 for ( std::list< TypeDecl* >::const_iterator tyvar = baseParameters->begin(); tyvar != baseParameters->end(); ++tyvar ) {173 boundVars.insert( (*tyvar)->get_name() );174 } // for168 // bind type variables from generic type instantiations 169 std::list< TypeDecl* > *baseParameters = type->get_baseParameters(); 170 if ( baseParameters && ! type->get_parameters().empty() ) { 171 for ( std::list< TypeDecl* >::const_iterator tyvar = baseParameters->begin(); tyvar != baseParameters->end(); ++tyvar ) { 172 boundVars.insert( (*tyvar)->get_name() ); 173 } // for 174 } // if 175 175 } // if 176 176 Type *ret = Mutator::mutate( type ); -
src/libcfa/gmp
r547e9b7 reb182b0 10 10 // Created On : Tue Apr 19 08:43:43 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun May 14 23:47:36201713 // Update Count : 912 // Last Modified On : Mon May 22 08:32:39 2017 13 // Update Count : 13 14 14 // 15 15 … … 35 35 Int ?=?( Int * lhs, long int rhs ) { mpz_set_si( lhs->mpz, rhs ); return *lhs; } 36 36 Int ?=?( Int * lhs, unsigned long int rhs ) { mpz_set_ui( lhs->mpz, rhs ); return *lhs; } 37 //Int ?=?( Int * lhs, const char * rhs ) { if ( mpq_set_str( lhs->mpz, rhs, 0 ) ) abort();return *lhs; }37 Int ?=?( Int * lhs, const char * rhs ) { if ( mpz_set_str( lhs->mpz, rhs, 0 ) ) { printf( "invalid string conversion\n" ); abort(); } return *lhs; } 38 38 39 39 char ?=?( char * lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); *lhs = val; return val; } -
src/main.cc
r547e9b7 reb182b0 64 64 bresolvep = false, 65 65 bboxp = false, 66 bcodegenp = false, 66 67 ctorinitp = false, 67 68 declstatsp = false, … … 306 307 OPTPRINT( "box" ) 307 308 GenPoly::box( translationUnit ); 309 310 if ( bcodegenp ) { 311 dump( translationUnit ); 312 return 0; 313 } 308 314 309 315 if ( optind < argc ) { // any commands after the flags and input file ? => output file name … … 377 383 378 384 int c; 379 while ( (c = getopt_long( argc, argv, "abBc defglLmnpqrstTvyzZD:F:", long_opts, &long_index )) != -1 ) {385 while ( (c = getopt_long( argc, argv, "abBcCdefglLmnpqrstTvyzZD:F:", long_opts, &long_index )) != -1 ) { 380 386 switch ( c ) { 381 387 case Ast: … … 393 399 case 'c': // print after constructors and destructors are replaced 394 400 ctorinitp = true; 401 break; 402 case 'C': // print before code generation 403 bcodegenp = true; 395 404 break; 396 405 case DeclStats: -
src/tests/.expect/64/gmp.txt
r547e9b7 reb182b0 4 4 conversions 5 5 y:97 6 y:12345678901234567890123456789 6 7 y:3 7 8 y:-3 … … 24 25 z:150000000000000000000 25 26 z:16666666666666666666 27 16666666666666666666, 2 16666666666666666666, 2 26 28 x:16666666666666666666 y:2 27 29 -
src/tests/gmp.c
r547e9b7 reb182b0 10 10 // Created On : Tue Apr 19 08:55:51 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun May 14 14:46:50201713 // Update Count : 53 012 // Last Modified On : Mon May 22 09:05:09 2017 13 // Update Count : 538 14 14 // 15 15 16 16 #include <gmp> 17 17 18 int main( ) {18 int main( void ) { 19 19 sout | "constructors" | endl; 20 20 short int si = 3; … … 25 25 sout | "conversions" | endl; 26 26 y = 'a'; 27 sout | "y:" | y | endl; 28 y = "12345678901234567890123456789"; 27 29 sout | "y:" | y | endl; 28 30 y = si; … … 62 64 z = x / 3; 63 65 sout | "z:" | z | endl; 66 sout | div( x, 3 ) | x / 3 | "," | x % 3 | endl; 64 67 [ x, y ] = div( x, 3 ); 65 68 sout | "x:" | x | "y:" | y | endl; 66 // sout | div( x, 3 ) | x / 3 | "," | x % 3 | endl;67 69 68 70 sout | endl; … … 72 74 fn = (Int){0}; fn1 = fn; // 1st case 73 75 sout | (int)0 | fn | endl; 74 fn = (Int){1}; fn2 = fn1; fn1 = fn;// 2nd case76 fn = 1; fn2 = fn1; fn1 = fn; // 2nd case 75 77 sout | 1 | fn | endl; 76 for ( int i = 2; i <= 200; i += 1 ) {78 for ( unsigned int i = 2; i <= 200; i += 1 ) { 77 79 fn = fn1 + fn2; fn2 = fn1; fn1 = fn; // general case 78 80 sout | i | fn | endl; … … 83 85 sout | "Factorial Numbers" | endl; 84 86 Int fact; 85 fact = (Int){1};// 1st case87 fact = 1; // 1st case 86 88 sout | (int)0 | fact | endl; 87 for ( int i = 1; i <= 40; i += 1 ) {89 for ( unsigned int i = 1; i <= 40; i += 1 ) { 88 90 fact = fact * i; // general case 89 91 sout | i | fact | endl; -
src/tests/tuplePolymorphism.c
r547e9b7 reb182b0 9 9 // Author : Rob Schluntz 10 10 // Created On : Tue Nov 16 10:38:00 2016 11 // Last Modified By : Rob Schluntz12 // Last Modified On : T ue Nov 16 10:39:18 201613 // Update Count : 211 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu May 18 18:05:12 2017 13 // Update Count : 4 14 14 // 15 15 16 16 // packed is needed so that structs are not passed with the same alignment as function arguments 17 17 __attribute__((packed)) struct A { 18 19 20 18 double x; 19 char y; 20 double z; 21 21 }; 22 22 23 23 __attribute__((packed)) struct B { 24 25 26 24 long long x; 25 char y; 26 long long z; 27 27 }; 28 28 … … 39 39 40 40 int main() { 41 42 41 int x1 = 123, x3 = 456; 42 double x2 = 999.123; 43 43 44 45 44 int i1 = 111, i3 = 222; 45 double i2 = 333; 46 46 47 48 47 int d1 = 555, d3 = 444; 48 double d2 = 666; 49 49 50 50 51 52 53 54 51 [i1, i2, i3] = ([x1, (int)x2, x3]) + ([9, 2, 3]); 52 [d1, d2, d3] = ([x1, x2, x3]) + ([9, 2, 3]); 53 printf("%d %g %d\n", i1, i2, i3); 54 printf("%d %g %d\n", d1, d2, d3); 55 55 56 57 58 59 60 56 [double, double, double] zzz; 57 zzz = [x1, x2, x3]; 58 printf("%g %g %g\n", zzz); 59 [x1, x2, x3] = zzz+zzz; 60 printf("%d %g %d\n", x1, x2, x3); 61 61 62 63 62 // ensure non-matching assertions are specialized correctly 63 g((A){ 1.21, 'x', 10.21}, (B){ 1111LL, 'v', 54385938LL }); 64 64 } 65 65 … … 73 73 // tab-width: 4 // 74 74 // End: // 75
Note: See TracChangeset
for help on using the changeset viewer.