Changes in / [d298e03:0661678]
- Files:
-
- 3 edited
-
doc/user/user.tex (modified) (14 diffs)
-
src/Parser/parser.yy (modified) (4 diffs)
-
src/tests/tuplePolymorphism.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/user/user.tex
rd298e03 r0661678 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Fri May 19 11:54:31 201714 %% Update Count : 1 73513 %% Last Modified On : Wed May 17 22:42:11 2017 14 %% Update Count : 1685 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 668 668 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; 669 669 \ie the null pointer is guaranteed to compare unequal to a pointer to any object or routine.} 670 An address is \newterm{sound}, if it points to a valid memory location in scope, \ie within the program's execution-environment andhas not been freed.670 An address is \newterm{sound}, if it points to a valid memory location in scope, \ie has not been freed. 671 671 Dereferencing an \newterm{unsound} address, including the null pointer, is \Index{undefined}, often resulting in a \Index{memory fault}. 672 672 … … 717 717 \end{quote2} 718 718 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. 719 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}.719 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 instruction decoding. 720 720 721 721 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. 722 (Similarly, an integer variable can contain multiple integer literals during its lifetime versus an integer constant representing a single literal during its lifetime , andlike a variable name, may not occupy storage as the literal is embedded directly into instructions.)722 (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.) 723 723 Hence, a pointer occupies memory to store its current address, and the pointer's value is loaded by dereferencing, \eg: 724 724 \begin{quote2} … … 736 736 \end{quote2} 737 737 738 Notice, an address has a \Index{duality}\index{address!duality}: a location in memory or the value at that location.738 Notice, an address has a duality\index{address!duality}: a location in memory or the value at that location. 739 739 In many cases, a compiler might be able to infer the best meaning for these two cases. 740 For example, \Index*{Algol68}~\cite{Algol68} infer s pointer dereferencing to select the best meaning for each pointer usage740 For example, \Index*{Algol68}~\cite{Algol68} inferences pointer dereferencing to select the best meaning for each pointer usage 741 741 \begin{cfa} 742 742 p2 = p1 + x; §\C{// compiler infers *p2 = *p1 + x;}§ … … 745 745 Unfortunately, automatic dereferencing does not work in all cases, and so some mechanism is necessary to fix incorrect choices. 746 746 747 Rather than inferring dereference, most programming languages pick one implicit dereferencing semantics, and the programmer explicitly indicates the other to resolve address-duality.747 Rather than dereference inferencing, most programming languages pick one implicit dereferencing semantics, and the programmer explicitly indicates the other to resolve address-duality. 748 748 In C, objects of pointer type always manipulate the pointer object's address: 749 749 \begin{cfa} … … 768 768 \end{cfa} 769 769 770 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).770 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. 771 771 \begin{cfa} 772 772 int x, y, ®&® r1, ®&® r2, ®&&® r3; … … 783 783 ®*®r2 = ((®*®r1 + ®*®r2) ®*® (®**®r3 - ®*®r1)) / (®**®r3 - 15); 784 784 \end{cfa} 785 When a reference operation appears beside a dereference operation, \eg ©&*©, they cancel out. 786 However, in C, the cancellation always yields a value (\Index{rvalue}).\footnote{ 785 When a reference operation appears beside a dereference operation, \eg ©&*©, they cancel out.\footnote{ 787 786 The unary ©&© operator yields the address of its operand. 788 787 If the operand has type ``type'', the result has type ``pointer to type''. 789 788 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}} 790 For a \CFA reference type, the cancellation on the left-hand side of assignment leaves the reference as an address(\Index{lvalue}):791 \begin{cfa} 792 (&®*®)r1 = &x; §\C{// (\&*) cancel giving address ofr1 not variable pointed-to by r1}§789 Hence, assigning to a reference requires the address of the reference variable (\Index{lvalue}): 790 \begin{cfa} 791 (&®*®)r1 = &x; §\C{// (\&*) cancel giving variable r1 not variable pointed-to by r1}§ 793 792 \end{cfa} 794 793 Similarly, the address of a reference can be obtained for assignment or computation (\Index{rvalue}): 795 794 \begin{cfa} 796 (&(&®*®)®*®)r3 = &(&®*®)r2; §\C{// (\&*) cancel giving address of r2, (\&(\&*)*) cancel giving address ofr3}§795 (&(&®*®)®*®)r3 = &(&®*®)r2; §\C{// (\&*) cancel giving address of r2, (\&(\&*)*) cancel giving variable r3}§ 797 796 \end{cfa} 798 797 Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth. … … 811 810 \end{cfa} 812 811 Furthermore, both types are equally performant, as the same amount of dereferencing occurs for both types. 813 Therefore, the choice between them is based solely on whether the address is dereferenced frequently or infrequently, which dictates the amount of implicitdereferencing aid from the compiler.812 Therefore, the choice between them is based solely on whether the address is dereferenced frequently or infrequently, which dictates the amount of dereferencing aid from the compiler. 814 813 815 814 As for a pointer type, a reference type may have qualifiers: … … 829 828 int & const cr = *0; §\C{// where 0 is the int * zero}§ 830 829 \end{cfa} 831 Note, constant reference -types do not prevent addressing errors because of explicit storage-management:830 Note, constant reference types do not prevent addressing errors because of explicit storage-management: 832 831 \begin{cfa} 833 832 int & const cr = *malloc(); 834 cr = 5;835 833 delete &cr; 836 834 cr = 7; §\C{// unsound pointer dereference}§ … … 856 854 where the \CFA declaration is read left-to-right (see \VRef{s:Declarations}). 857 855 858 In contra st 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}.859 \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.856 In contract 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}. 857 \Index*{Java}'s reference types to objects (because 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. 860 858 861 859 \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. 862 860 There are three initialization contexts in \CFA: declaration initialization, argument/parameter binding, return/temporary binding. 863 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. 864 In contrast, the left-hand side of assignment has an address that has a duality. 865 Therefore, for pointer/reference initialization, the initializing value must be an address (\Index{lvalue}) not a value (\Index{rvalue}). 866 \begin{cfa} 867 int * p = &x; §\C{// must have address of x}§ 868 int & r = x; §\C{// must have address of x}§ 869 \end{cfa} 870 Therefore, it is superfluous to require explicitly taking the address of the initialization object, even though the type is incorrect. 871 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. 872 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. 873 (\CFA extends pointer initialization so a variable name is automatically referenced, eliminating the unsafe assignment.) 874 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. 875 \begin{cfa} 876 int & f( int & r ); §\C{// reference parameter and return}§ 861 For reference initialization (like pointer), the initializing value must be an address (\Index{lvalue}) not a value (\Index{rvalue}). 862 \begin{cfa} 863 int * p = &x; §\C{// both \&x and x are possible interpretations in C}§ 864 int & r = x; §\C{// x unlikely interpretation, because of auto-dereferencing}§ 865 \end{cfa} 866 C allows ©p© to be assigned with ©&x© or ©x© (many compilers warn about the latter assignment). 867 \CFA allows ©r© to be assigned ©x© only because it inferences a dereference for ©x©, by implicitly inserting a address-of operator, ©&©, before the initialization expression because a reference behaves like the variable name it is pointing-to. 868 Similarly, when a reference is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason. 869 \begin{cfa} 870 int & f( int & rp ); §\C{// reference parameter and return}§ 877 871 z = f( x ) + f( y ); §\C{// reference operator added, temporaries needed for call results}§ 878 872 \end{cfa} 879 Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r © can be locally reassigned within ©f©.873 Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©rp© can be locally reassigned within ©f©. 880 874 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. 881 \begin{cfa}882 int temp1 = f( x ), temp2 = f( y );883 z = temp1 + temp2;884 \end{cfa}885 This implicit referencing is crucial for reducing the syntactic burden for programmers when using references;886 otherwise references have the same syntactic burden as pointers in these contexts.887 875 888 876 When a pointer/reference parameter has a ©const© value (immutable), it is possible to pass literals and expressions. 889 877 \begin{cfa} 890 void f( ®const® int & cr );891 void g( ®const® int * cp );878 void f( ®const® int & crp ); 879 void g( ®const® int * cpp ); 892 880 f( 3 ); g( &3 ); 893 881 f( x + y ); g( &(x + y) ); … … 895 883 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. 896 884 (The ©&© is necessary for the pointer-type parameter to make the types match, and is a common requirement for a C programmer.) 897 \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{ 898 If whole program analysis is possible, and shows the parameter is not assigned, \ie it is ©const©, the temporary is unnecessary.} 899 \begin{cfa} 900 void f( int & r ); 901 void g( int * p ); 885 \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. 886 \begin{cfa} 887 void f( int & rp ); 888 void g( int * pp ); 902 889 f( 3 ); g( &3 ); §\C{// compiler implicit generates temporaries}§ 903 890 f( x + y ); g( &(x + y) ); §\C{// compiler implicit generates temporaries}§ … … 907 894 The implicit conversion allows seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call. 908 895 909 %\CFA attempts to handle pointers and references in a uniform, symmetric manner. 910 However, C handles routine objects in an inconsistent way. 911 A routine object is both a pointer and a reference (particle and wave). 912 \begin{cfa} 913 void f( int i ); 914 void (*fp)( int ); 915 fp = f; §\C{// reference initialization}§ 916 fp = &f; §\C{// pointer initialization}§ 917 fp = *f; §\C{// reference initialization}§ 896 While \CFA attempts to handle pointers and references in a uniform, symmetric manner, C handles routine objects in an inconsistent way: a routine object is both a pointer and a reference (particle and wave). 897 \begin{cfa} 898 void f( int p ) {...} 899 void (*fp)( int ) = &f; §\C{// pointer initialization}§ 900 void (*fp)( int ) = f; §\C{// reference initialization}§ 901 (*fp)(3); §\C{// pointer invocation}§ 918 902 fp(3); §\C{// reference invocation}§ 919 (*fp)(3); §\C{// pointer invocation}§920 903 \end{cfa} 921 904 A routine object is best described by a ©const© reference: 922 905 \begin{cfa} 923 const void (&fr)( int ) = f; 924 fr = ... §\C{// error, cannot change code}§ 925 &fr = ...; §\C{// changing routine reference}§ 926 fr( 3 ); §\C{// reference call to f}§ 927 (*fr)(3); §\C{// error, incorrect type}§ 906 const void (&fp)( int ) = f; 907 fp( 3 ); 908 fp = ... §\C{// error, cannot change code}§ 909 &fp = ...; §\C{// changing routine reference}§ 928 910 \end{cfa} 929 911 because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{ 930 912 Dynamic code rewriting is possible but only in special circumstances.} 931 913 \CFA allows this additional use of references for routine objects in an attempt to give a more consistent meaning for them. 932 933 This situation is different from inferring with reference type being used ...934 935 914 936 915 … … 1550 1529 int main() { 1551 1530 * [int](int) fp = foo(); §\C{// int (*fp)(int)}§ 1552 sout | fp( 3 ) | endl;1531 sout | fp( 3 ) | endl; 1553 1532 } 1554 1533 \end{cfa} … … 2166 2145 ®int j = 0;® §\C{// disallowed}§ 2167 2146 case 1: 2168 {2147 { 2169 2148 ®int k = 0;® §\C{// allowed at different nesting levels}§ 2170 2149 ... -
src/Parser/parser.yy
rd298e03 r0661678 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 y 18 18:06:17201713 // Update Count : 23 3812 // Last Modified On : Thu Mar 30 15:42:32 2017 13 // Update Count : 2318 14 14 // 15 15 … … 85 85 } // for 86 86 } // distExt 87 88 bool forall = false; // aggregate have one or more forall qualifiers ?89 87 %} 90 88 … … 1558 1556 sue_type_specifier: // struct, union, enum + type specifier 1559 1557 elaborated_type 1560 | type_qualifier_list 1561 { if ( $1->type != nullptr && $1->type->forall ) forall = true; } // remember generic type 1562 elaborated_type 1563 { $$ = $3->addQualifiers( $1 ); } 1558 | type_qualifier_list elaborated_type 1559 { $$ = $2->addQualifiers( $1 ); } 1564 1560 | sue_type_specifier type_qualifier 1565 1561 { $$ = $1->addQualifiers( $2 ); } … … 1617 1613 { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); } 1618 1614 | aggregate_key attribute_list_opt no_attr_identifier_or_type_name 1619 { 1620 typedefTable.makeTypedef( *$3 ); // create typedef 1621 if ( forall ) typedefTable.changeKind( *$3, TypedefTable::TG ); // possibly update 1622 forall = false; // reset 1623 } 1615 { typedefTable.makeTypedef( *$3 ); } 1624 1616 '{' field_declaration_list '}' 1625 1617 { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $6, true )->addQualifiers( $2 ); } -
src/tests/tuplePolymorphism.c
rd298e03 r0661678 9 9 // Author : Rob Schluntz 10 10 // Created On : Tue Nov 16 10:38:00 2016 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T hu May 18 18:05:12 201713 // Update Count : 411 // Last Modified By : Rob Schluntz 12 // Last Modified On : Tue Nov 16 10:39:18 2016 13 // Update Count : 2 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 double x;19 char y;20 double z;18 double x; 19 char y; 20 double z; 21 21 }; 22 22 23 23 __attribute__((packed)) struct B { 24 long long x;25 char y;26 long long z;24 long long x; 25 char y; 26 long long z; 27 27 }; 28 28 … … 39 39 40 40 int main() { 41 int x1 = 123, x3 = 456;42 double x2 = 999.123;41 int x1 = 123, x3 = 456; 42 double x2 = 999.123; 43 43 44 int i1 = 111, i3 = 222;45 double i2 = 333;44 int i1 = 111, i3 = 222; 45 double i2 = 333; 46 46 47 int d1 = 555, d3 = 444;48 double d2 = 666;47 int d1 = 555, d3 = 444; 48 double d2 = 666; 49 49 50 50 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);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 [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);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 // ensure non-matching assertions are specialized correctly63 g((A){ 1.21, 'x', 10.21}, (B){ 1111LL, 'v', 54385938LL });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.