Changeset 5d3a952 for doc/theses
- Timestamp:
- Apr 24, 2019, 9:31:21 PM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 69c37cc
- Parents:
- 39de1c5
- Location:
- doc/theses/aaron_moss_PhD/phd
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/aaron_moss_PhD/phd/generic-types.tex
r39de1c5 r5d3a952 27 27 int int_list_head( const struct int_list* ls ) { return ls->value; } 28 28 29 $\C[\textwidth]{// all code must be duplicated for every generic instantiation}$29 // all code must be duplicated for every generic instantiation 30 30 31 31 struct string_list { const char* value; struct string_list* next; }; … … 40 40 { return ls->value; } 41 41 42 $\C[\textwidth]{// use is efficient and idiomatic}$42 // use is efficient and idiomatic 43 43 44 44 int main() { … … 65 65 struct list { void* value; struct list* next; }; 66 66 67 $\C[\textwidth]{// internal memory management requires helper functions}$67 // internal memory management requires helper functions 68 68 69 69 void list_insert( struct list** ls, void* x, void* (*copy)(void*) ) { … … 75 75 void* list_head( const struct list* ls ) { return ls->value; } 76 76 77 $\C[\textwidth]{// helpers duplicated per type}$77 // helpers duplicated per type 78 78 79 79 void* int_copy(void* x) { … … 105 105 #include <stdio.h> $\C{// for printf}$ 106 106 107 $\C[\textwidth]{// code is nested in macros}$107 // code is nested in macros 108 108 109 109 #define list(N) N ## _list … … 127 127 define_list(string, const char*); $\C[3in]{// defines string\_list}$ 128 128 129 $\C[\textwidth]{// use is efficient, but syntactically idiosyncratic}$129 // use is efficient, but syntactically idiosyncratic 130 130 131 131 int main() { … … 156 156 forall(otype T) struct list { T value; list(T)* next; }; 157 157 158 $\C[\textwidth]{// single polymorphic implementation of each function}$159 $\C[\textwidth]{// overloading reduces need for namespace prefixes}$158 // single polymorphic implementation of each function 159 // overloading reduces need for namespace prefixes 160 160 161 161 forall(otype T) void insert( list(T)** ls, T x ) { … … 167 167 forall(otype T) T head( const list(T)* ls ) { return ls->value; } 168 168 169 $\C[\textwidth]{// use is clear and efficient}$169 // use is clear and efficient 170 170 171 171 int main() { -
doc/theses/aaron_moss_PhD/phd/resolution-heuristics.tex
r39de1c5 r5d3a952 46 46 47 47 \begin{itemize} 48 \item If either operand is a floating-point type, the common type is the size of the largest floating-point type. If either operand is !_Complex!, the common type is also !_Complex!.48 \item If either operand is a floating-point type, the common type is the size of the largest floating-point type. If either operand is !_Complex!, the common type is also \linebreak !_Complex!. 49 49 \item If both operands are of integral type, the common type has the same size\footnote{Technically, the C standard defines a notion of \emph{rank} in \cite[\S{}6.3.1.1]{C11}, a distinct value for each \lstinline{signed} and \lstinline{unsigned} pair; integral types of the same size thus may have distinct ranks. For instance, though \lstinline{int} and \lstinline{long} may have the same size, \lstinline{long} always has greater rank. The standard-defined types are declared to have greater rank than any types of the same size added as compiler extensions.} as the larger type. 50 50 \item If the operands have opposite signedness, the common type is !signed! if the !signed! operand is strictly larger, or !unsigned! otherwise. If the operands have the same signedness, the common type shares it. … … 106 106 107 107 \begin{cfa} 108 forall(otype T, otype U) void f$\(_1\)$(T, U); $\C[3. 25in]{// polymorphic}$109 forall(otype T) void f$\(_2\)$(T, T); $\C[3. 25in]{// less polymorphic}$110 forall(otype T) void f$\(_3\)$(T, int); $\C[3. 25in]{// even less polymorphic}$111 forall(otype T) void f$\(_4\)$(T*, int); $\C[3. 25in]{// least polymorphic}$108 forall(otype T, otype U) void f$\(_1\)$(T, U); $\C[3.125in]{// polymorphic}$ 109 forall(otype T) void f$\(_2\)$(T, T); $\C[3.125in]{// less polymorphic}$ 110 forall(otype T) void f$\(_3\)$(T, int); $\C[3.125in]{// even less polymorphic}$ 111 forall(otype T) void f$\(_4\)$(T*, int); $\C[3.125in]{// least polymorphic}$ 112 112 \end{cfa} 113 113 … … 196 196 \end{cfa} 197 197 198 In C semantics, this example is unambiguously upcasting !32! to !unsigned long long!, performing the shift, then downcasting the result to !unsigned!, at totalcost $(1,0,3,1,0,0,0)$.198 In C semantics, this example is unambiguously upcasting !32! to !unsigned long long!, performing the shift, then downcasting the result to !unsigned!, at cost $(1,0,3,1,0,0,0)$. 199 199 If ascription were allowed to be a first-class interpretation of a cast expression, it would be cheaper to select the !unsigned! interpretation of !?>>?! by downcasting !x! to !unsigned! and upcasting !32! to !unsigned!, at a total cost of $(1,0,1,1,0,0,0)$. 200 200 However, this break from C semantics is not backwards compatibile, so to maintain C compatibility, the \CFA{} resolver selects the lowest-cost interpretation of the cast argument for which a conversion or coercion to the target type exists (upcasting to !unsigned long long! in the example above, due to the lack of unsafe downcasts), using the cost of the conversion itself only as a tie-breaker.
Note: See TracChangeset
for help on using the changeset viewer.