Changeset 3c1e432
- Timestamp:
- Apr 17, 2025, 9:51:57 PM (5 months ago)
- Branches:
- master
- Children:
- 7a43045
- Parents:
- 0d41e600
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/autogen.md
r0d41e600 r3c1e432 1 # Review of Auto generation1 # Review of Auto-generation 2 2 There have been known issues with auto-generated routines for a long time. Although no one has time to leap onto the problem right now, we figure people should start thinking about that. And the first part of that is to get all the grievances with the current system. 3 3 … … 6 6 7 7 ## C Compatibility 8 Old C code should continue to work without any (or mi mimal). Furthermore, C-style code should usually work when mixed with CFA features. This includes behaviour not implemented as operators in CFA (such as field access and designators) as well as those that do.8 Old C code should continue to work without any (or minimal). Furthermore, C-style code should usually work when mixed with CFA features. This includes behaviour not implemented as operators in CFA (such as field access and designators) as well as those that do. 9 9 10 Note, that some CFA feature can disable C Compatibility, for instance visibility modifiers on fields might disable by-field initialization . However, orthogonal features, such as polymorphism, should not.10 Note, that some CFA feature can disable C Compatibility, for instance visibility modifiers on fields might disable by-field initialization (PAB explain). However, orthogonal features, such as polymorphism, should not. 11 11 12 12 ## Life-Time Functions 13 We want to get the life-time functions (destructor, copy assignment and copy construction) without having to write them when they are obvious .13 We want to get the life-time functions (destructor, copy assignment and copy construction) without having to write them when they are obvious as does C++. 14 14 15 15 This actually has a lot of overlap with C Compatibility, in that these are also things you can do with them in C. So these functions should act like the primitive operations in C in those cases. 16 16 17 17 ## Custom Implementations 18 We should be able to write custom implementations of the operators. These can be used to replace one of the generated functions. It also or toadd a new operator for the type.18 We should be able to write custom implementations of the operators. These can be used to replace one of the generated functions. It also can add a new operator for the type. 19 19 20 20 ## Purposeful Missing Functions 21 For the C-Compatibility's functions and life-time functions, sometimes we do not need, and in fact do not want, some of those functions. These should be possible to remove and any attempt to use them should be rejected oncompilation.21 For the C-Compatibility's functions and life-time functions, sometimes we do not need, and in fact do not want, some of those functions. These should be possible to remove and any attempt to use them should be rejected at compilation. 22 22 23 23 # Problems … … 28 28 29 29 ### Value Call Semantics 30 This is actually more general issue than autogenerated functions, but the thecopy constructor and copy assignment operators still take their source argument by value. They have to be copied in C-style to implement the copy operator. When it is fixed, then autogeneration will have to be updated as well.30 This is actually more general issue than autogenerated functions, but the copy constructor and copy assignment operators still take their source argument by value. They have to be copied in C-style to implement the copy operator. When it is fixed, then autogeneration will have to be updated as well. 31 31 32 32 Current Forms: … … 39 39 40 40 ### Unused Assertions Still Added to the Assertion List 41 All assertions on the type dec klaration are used in all autogenerated functions even if they are never used. For example:41 All assertions on the type declaration are used in all autogenerated functions even if they are never used. For example: 42 42 43 43 The declaration of: … … 57 57 void ?{}(Cell(T)&, T); 58 58 59 If these assertions were reduced to the minim ial required assertions the result would instead look something like the:59 If these assertions were reduced to the minimal required assertions the result would instead look something like the: 60 60 forall(T* | { void ?{}(T&); }) 61 61 void ?{}(Cell(T)&); … … 71 71 This leads to exponential thunk generation for `Cell(Cell(int))` (or a matrix represented `vector(vector(vector(int)))`). 72 72 73 ### Autogened Functions cannot use Avai ble Functions73 ### Autogened Functions cannot use Available Functions 74 74 If you supply an implementation for one of the autogenerated functions, it will not be used while generating other functions. 75 75 76 Consider a case with a custom copy constructor but don't define an assignment operator. The current (problematic) behaviour reimplements the assignment operator member-wise. The ideal solution would be to create a new implementation of the operator that applies the appropr ate destructor, then the custom copy constructor. Although this implementation may be slower, it will have correct behaviour if the other operators are implemented properly.76 Consider a case with a custom copy constructor but don't define an assignment operator. The current (problematic) behaviour reimplements the assignment operator member-wise. The ideal solution would be to create a new implementation of the operator that applies the appropriate destructor, then the custom copy constructor. Although this implementation may be slower, it will have correct behaviour if the other operators are implemented properly. 77 77 78 An alternate behaviour would simply to remove the assignment operator entirely unless the users explicit y provides one. This is more similar to C++'s "The Rule of Three" (or "The Rule of Five" with move operations), where all three of the lifetime functions must be redefined if any of them are. The advantage of the new assignment operator (mentioned in the "ideal solution") is that it avoids a similar rule of three, needing only destruction and copy construction for proper lifetime behaivour.78 An alternate behaviour would simply to remove the assignment operator entirely unless the users explicit provides one. This is more similar to C++'s "The Rule of Three" (or "The Rule of Five" with move operations), where all three of the lifetime functions must be redefined if any of them are. The advantage of the new assignment operator (mentioned in the "ideal solution") is that it avoids a similar rule of three, needing only destruction and copy construction for proper lifetime behaviour. 79 79 80 80 ## Problems With Removed Functions 81 81 82 82 ### Failed Autogeneration Leaves Behind Declaration 83 All autogenerated functions are a checked by attempting to resolve it. If there is an errorthan the autogenerated function is removed. But that only removes the definition, so it can still be considered as a candidate for resolution. The following code will compile but fail during linking.83 All autogenerated functions are checked by attempting to resolve them. If there is an error, than the autogenerated function is removed. But that only removes the definition, so it can still be considered as a candidate for resolution. The following code will compile but fail during linking. 84 84 85 85 forall(T *) struct Cell { T x; }; … … 89 89 90 90 ### Overriding a Function can Lead to Problems 91 Implementing your o ven version of a function should always override the autogenerated function. This does not happen, especially if the declared function does not use the exact same assertions as the autogenerated function (provided via the type declaration itself).91 Implementing your own version of a function should always override the autogenerated function. This does not happen, especially if the declared function does not use the exact same assertions as the autogenerated function (provided via the type declaration itself). 92 92 93 93 (This issue is filled as Trac Ticket 186.) … … 107 107 vector v = {capacity: 128}; 108 108 109 The designator syntax (includ ing in the example) being different from C is also a problem for compatability, but does not change their use in pure Cforall.109 The designator syntax (included in the example) being different from C is also a problem for compatibility, but does not change their use in pure Cforall. 110 110 111 111 ### Non-Intuitive Reference Initializer … … 126 126 (this.x){ x }; 127 127 // A correct way to implement this operation. 128 // ?{}(*(int*)&this.x, x); 128 // ?{}(*(int*)&this.x, x); // remove const 129 129 } 130 130 … … 142 142 10%: anything else 143 143 144 (This was not counting copy assignment, although it could be considered an optimization of dest ory and then copy (re)construct.)144 (This was not counting copy assignment, although it could be considered an optimization of destroy and then copy (re)construct.) 145 145 146 146 ### Incorrect Field Detection … … 150 150 151 151 ### No-op Constructor 152 This may be solved, in some cases, but there is no t a clear interface for not running constructors. It would be nice to, like in C, to leave stack allocated variable uninitialized, this is mostly a preformance issue but can allow you do declare a variable before the information to construct it is read.152 This may be solved, in some cases, but there is no clear interface to specify that a construction should not be run. It would be nice, like in C, to leave stack allocated variable uninitialized, this is mostly a performance issue but can allow you do declare a variable before the information to construct it is read. 153 153 154 154 However, if a constructor is run, then all of its components should be initialized by default.
Note:
See TracChangeset
for help on using the changeset viewer.