Home

- HSR - Institutional Repository

image

Contents

1. Preferences type filter text Settings gt General PAnt These settings are global to the entire workspace They are overridden by project specific settings YC C Appearance Error Parsers PETTI YBuild Build Variables HEBEN cones CDT GCC Build Output Parser Shared Clear Entries Environment CDT GCC Built in Compiler Settings Shared PR a RACDT Managed Build Setting Entries Shared Reset Make Targets CDT User Setting Entries Shared gt Makefile Editor lt Contributed Scannerinfo Entries Shared Settim li Test Plugin Mock Base Provider Subclass Shared Code Analysis di Test Plugin Mock Editable Language Settings Provider Shared Code Style Test Plugin Mock Language Settings Base Provider Shared Debug di Test Plugin Mock Language Settings Provider Shared PEditor li Test Plugin Mock Listener Language Settings Provider Shared File Types di Test Plugin Mock Serializable Language Settings Provider Shared indir Test Plugin Setting Entries UI Tester Shared Language Mappings gt New CDT Project Wiz sheet Bins Language Settings Provider Options Task Tags Command to get compiler specs Template Default Val Voda Recommanders S COMMAND E P v dD std c 11 SIINPUTS Browse pilis C Allocate console in the Console View gt Install Update PJava Library Hover Maven Mylyn Plug in Development Run Debug PScala Scala Worksheet gt Team Validation gt
2. 27 3 Analysis is truly allowed to be NULL or if this is just a safety measurement for errors Thus this example could for instance represent an optional refer ence 1 void set boost optional lt int amp gt i 2 if i 3 xi 3 4 5 In this representation the developer expressed that the function pa rameter is optional and if available is a reference to an integer The same thing could also be expressed though less explicitly using non_owning_ptr as reference 1 void set boost optional lt const non_owning_ptr lt int gt gt i 2 if i 3 i 3 4 5 The non_owning_ptr still makes clear that i is a non owning refer ence but is slightly less convenient to use And since non_owning_ptr can be empty the optional could also be implemented without boost optional 1 void set const non_owning_ptr lt int gt i 2 if i 3 xi 3 4 Bo oh In this version it is not explicitly communicated that the parameter is optional Depending on other factors such as coding conven tions of the project the simpler notation might justify this loss of semantics As one can see there is an almost infinite number of combinations possible and often there is more than one correct solution It is 28 3 3 Replacing the use of raw pointers in the responsibility of the developer to communicate his intentions by using an appropriate combination of the available smart pointers aft
3. Fig C C Projects v 5Demo sl Includes gt Debug gt main cpp pointers cpp w hn pointers h e POINTERS_H_ 4 bar int void Writable Le main cpp i include pointers h include lt memory gt void fooCint x Sint main ar int x new int 1 bar x delete x o ea t r ao E Console x CDT Build Console Demo k 08 22 04 Build Finished took 732ms Smart Insert 10 Figure D 1 The plug in displays raw pointer issues C C Demo main cpp Eclipse Platform fig C C Projects x O jas gt Demo gt Includes gt Debug gt smartor gt main cpp gt pointers cpp w pointers h POINTERS_H_ bar int void Writable Figure D 2 main cpp i include pointers h include lt memory gt include lt exempt_ptr h gt Svoid fooCexempt_ptr lt int gt x Sint main std unique_ptr lt int gt x new int 1 bar x get sera en E console x COT Suli Console Dema 08 22 04 Build Finished took 732ms Smart Insert 5 3 The plug in removes delete statements calls the get function and adds include statements if needed As shown in figure D 2 the plug in can also add include statements and in the case of a non owning pointer it also adds the needed header file to the project and setups the include path in the project 110 D
4. INSTITUTE FOR SOFTWARE HSR HOCHSCHULE FUR TECHNIK RAPPERSWIL FHO Fachhochschule Ostschweiz Bachelor Thesis Smartor Dress Naked C Pointers to Smart Pointers Andr Frohlich Christian Mollekopf Spring Term 2013 Supervised by Prof Peter Sommerlad Abstract C allows the use of raw pointers as they exist in plain C Unfor tunately they can t demonstrate the semantic role of their usage as they are a very low level concept Furthermore they often lead to memory leaks and hard to understand source code Better alternatives in C are smart pointers Smart pointers are a group of wrappers around raw pointers They provide a facility that covers the memory management and adds semantic information on what exactly the pointer is used for The goal of our project is to develop an Eclipse CDT plug in assisting a developer in finding and converting raw pointers into smart pointers In addition it serves as an experiment on how the Scala language helps to write code that manipulates an abstract syntax tree Our thesis contains an analysis of pointer roles and their possible transformations into smart pointers The plug in assists a devel oper in detecting and transforming raw pointers into suitable smart pointers by displaying a marker in the editor and offering appropri ate quick fixes Using Scala resulted in cleaner and more readable source code Scala s match statement provides a neat way to match aga
5. 3 Class Car public Vehicle a f 5 public 6 Car int ps 7 8 9 class Engine 11 template lt typename T gt 12 class SpecializedCar public Vehicle 13 A 14 public 15 SpecializedCar int ps Software DOOM3 Sourcecode 37 3 Analysis 16 Listing 3 1 Vehicle class hierarchy 3 4 2 Scope and Limitations Only std unique_ptr and non_owning_ptr are considered for the refactorings because all roles can be expressed with them see also section 3 3 1 on page 29 As strings and arrays are a special case of pointers for which specific smart pointers exist this analysis doesn t consider them See 3 1 on pago 13 It is assumed that a single identifier always either stands for an own ing pointer or a non owning pointer but never for both Therefore a construct like this would not be supported 1 int getRef 2 int i 3 if condition 4 i new int 5 else 4 6 i getRef 7 s if condition 9 delete i 10 It is not possible to choose a suitable smart pointer for i because the identifier changes the semantics in the codepaths Further are any problems resulting from misuse of pointers such as assigning numbers to a pointer other than nullptr not taken into account 38 3 4 Refactoring Cases 3 4 3 Starting points For the analysis three different starting points were chosen e A local pointer variable int x e A pointer function parameter void fo
6. we recommend Programming in Scala P by Martin Odersky Lex Spoon and Bill Venners scala lang org A Tour of Scala Odersky Spoon and Venners Programming in Scala 2 Objectives 2 1 Motivation Using raw pointers in C is complex error prone and results of ten in hard to understand code Manual resource management can become very complex as the number of code path s grows and con sequently becomes a maintenance burden as even minor changes to the code could potentially break the resource management Further pointers can have various semantics including C implementation of a reference strings arrays optional return values or arguments ownership transfer etc Unfortunately there are only few tools for the developer to communicate the intended meaning This results in unclear responisbilities in programming interfaces which can ul timately lead to dangling pointers double deletes memory leaks and alike Smart pointers address those problems by giving the pointer a type expressing the meaning and by moving the resource management to the library This leads to more expressive code While smart pointers have been long existing in various third party libraries C 11 now standardized std unique_ptr and std shared_ptr removing the last barrier from widespread use of smart pointers 2 2 Vision The goal of this project is to analyse in which cases raw point ers can be replaced with which smart pointer
7. 3 4 7 Function parameter owning pointer A function takes ownership of a pointer if either the function deletes the pointer itself like a disposal function or if the function trans fers ownership somewhere See also 3 3 2 on page 30 Example void sell Car void destroyCar Car c delete c void trySellCar Car car 1 2 3 4 s 6 7 8 9 We can t sell this junk 50 10 11 12 13 14 15 16 17 18 19 20 21 3 4 Refactoring Cases if car gt ps lt 42 destroyCar car else sell car void foo Car car new Car 42 trySellCar car trySellCar would transfer the ownership of the pointer to sell if it s ps were greater than 42 but instead passes it to the disposal function destroyCar We know that destroyCar takes ownership of the pointer because it deletes it We assume that sell takes ownership of the pointer If it wouldn t car would be owning in one codepath and non owning in the other Example refactored oo JD 0 Ba Ww N e e BP H Bo NY FO 15 16 17 18 19 20 void sell Cark void destroyCar Car c delete c void trySellCar std unique_ptr lt Car gt car We can t sell this junk if car gt ps lt 42 destroyCar car get else sell car get void foo Car car new Car 42 trySellCar std unique_ptr lt Car gt car ol 3 Analysis 2 The pointer can be refactor
8. 4 Refactoring Cases 1 void setupCar non_owning_ptr lt Car gt car 2 3 car gt setup 4 6 void setup 7 A 8 Car car new Car 42 9 setupCar make_nonowning car 10 delete car The pointer can be refactored to a non_owning_ptr Each caller must be adjusted to use make_nonowning because the constructor of non_owning_ptr is explicit Limitations and Edge Cases e The same limitations as for a local pointer apply as the pa rameter behaves inside the scope of the function like a local variable e If a caller already uses a non_owning_ptr but extracts the raw pointer using get the smart pointer can passed directly If the pointer is extracted from another smart pointer using get it still needs to be wrapped using make_non_owning 3 4 9 Return value owning pointer A function may pass ownership with a pointer as return value One pattern returning an owning pointer is the factory method pat tern 13 Wikipedia Factory Method 59 3 Analysis Example 1 Vehicle createVehicle 2 A 3 return new Car 4 y 6 void main mf 8 Vehicle vehicle createVehicle o createVehicle allocates the Car object and then transfers ownership to the caller It is therefore a factory function Specific Example e sourcefile DOOM 3 neo tools radiant splines cpp 777 787 e function idCameraDef start NewCamera e variable cameraPosition 1 idCameraPosition idCameraDef startNe
9. N e 10 after refactoring 1 void foo non_owning_ptr lt Car gt car 12 4 13 14 15 Car car new Car 42 16 foo car Before the refactoring foo Car is selected After the refac toring tfoo Vehiclex is selected because the raw pointer ar gument no longer matches the non_owning_ptr parameter A possible migration path for this problem would be to provide an overloaded wrapper function that takes the raw pointer wraps it in a smart pointer and delegates the call to the smart pointer version 1 void foo non_owning_ptr lt Car gt car 2 1 3 E 40 3 4 Refactoring Cases wrapper void foo Car car foo non_owning_ptr lt Car gt car o 00 ID A A This way the caller code doesn t need to be adjusted and there is no danger of a new overload being selected Note that if all callers can be adjusted before the refactoring this problem can be avoided entirely This may however not be possible if the code is part of the API of a library Note that the same problem applies to a virtual dispatch as well 1 struct Base 2 virtual foo Car Sue 4 struct Derived 5 before the refactoring 6 virtual foo Car 7 after the refactoring 8 virtual foo non_owning_ptr lt Car gt 9 y 10 1 Car car new Car 42 12 Base base new Derived base gt foo car w The call to base gt foo resulted in a call to Derived foo before the refactoring due to the virtual dispatch mechan
10. WindowBuilder i PXML Restore Defaults Apply Figure B 2 The addition of the std c 11 option is required The compiler options can be altered in the preferences Under C C Build gt Setting in the Discovery tab the CDT GCC Built in Compiler setting can be specified It is required to add the std c 11 option as showed in figure B 2 Depending on the version of GCC it can be required to add aditional symbols Symbols tab the symbols can Under C C General Path and Symbols in the be edited as shown in figure B 3 97 B Environment Properties for Demo T Paths and Symbols Configuration Debug Active M Show built in values 3 Import Settings Export Settings Restor Dafa O Aey Bu Cancel Figure B 3 Additional symbols can be defined B 2 8 Target File When the plug in is run Eclipse launches a new instances with the plug in and its dependencies A target file allows to specify all required plug in dependencies a plug in needs to launch Eclipse automaticaly downloads them if necessary It is an alternative to configuring run configurations ins Eclipse The target file can be activated by opening it and clicking on Set as Target Platform B 3 Eclipse Static Code Analysis Eclipse provides a framework for static code analysis called Codan CODe ANalysis It allows plug ins to provid
11. and other intention revealing constructs so eres roces 23 3 2 3 std unique ptr Gr de a a a 24 ee ee ee ae ee 24 bt ba ee Ee ER 24 3 2 6 std auto_ptr deprecated 25 3 2 MOMSOWNINE PU e ea 2 4 2 25 28 2 25 3 2 8 optional e o an a 25 uefa Y a 26 ce 27 A reer ee ee ee 29 3 3 2 An approach for automatic determination of a suitable smart pointer 30 Contents get Am one gie ay aa Ge Bein GS Bee Gy 34 3 4 1 Format sani a a ead 00 2 0 0000 37 of Boe eae oe ee 38 eon ee ee ee ee ae 39 3 4 4 Default Cases 42 eos me eee 43 3 4 6 Local pointer non owning 47 bo er 50 B18 Function parameter Non owning pointer 53 Sean oe eae 55 Be 57 59 Ge grb hs ee AN cee 61 63 4 1 Checker 63 ee se ea a ee es S 65 4 1 2 Pattern matching basar AA 67 A A AI 69 4 2 1 Architecture 70 E ee ee ee ee 72 4 2 3 Includesl 74 a o eo ee as 74 CA A 75 La ARA A a ee 76 a a aa 76 ETT 77 4 6 2 yal Vs wae de A e OE s 77 4 6 3 Pattern Matching z 4 264 4 44 4 44 78 4 6 4 Exception handling 2 4 22444444 44 4 78 Rape we Woe ee ee ee ee et 79 4 6 6 foreach 0 0 0 0 0 0 008 4 79 4 6 7 Concise notation 79 4 6 8 Java Conversions 4 80 ara a e e 81 Contents 83 Se he eee Gente Gece erg at eee eee 83 5 2 Future Wohl 6 2 2
12. and that work every new developer will have to do again Smart pointers give developers the tools to express their intentions in a way that also a compiler can understand which might be of even greater value than the automatic memory management By recognizing the use of raw pointers in an existing codebase any by providing suitable refactorings we can help developers to spot and fix the use of raw pointers Although the plugin is not able to automatically determine the suitable smart pointer the developer is at least supported by heuristics that work in many cases 62 4 Implementation The implementation of the smartor plug in is split into two major parts the checker and the quickfixes The checker is responsible for identifying the starting points see Section 3 4 3 on page 39 in the code which are then marked using a marker The quickfix is responsible for executing a predefined refactoring For each marker quickfixes are registered which are then proposed to the user If a quickfix is activated by the user the quickfix im plementation commits it s modifications to the source code ovoid foo fy IEF Convert to std unique_ptr Figure 4 1 A marker highlighting a raw pointer argument with two proposed quickfixes The plug in was developed using Scala the project results in a single plug in that can be used in Eclipse 4 1 Checker The checker is responsible for identifying problematic sections in
13. and to develop an Eclipse CDT plug in that helps developers to spot existing uses of 2 Objectives raw pointers and fix them with a corresponding smart pointer As many of those transformations are non trivial the goal is to iden tify possible transformations and to implement only a subset deemed feasible The plugin should for instance handle the following cases e raw pointers passed as arguments where the function doesn t take ownership of the resource should be converted to a con figurable smart pointer non_owning_ptr which is likely to be standardized in upcoming versions of the C standard e raw pointers passed as arguments where the function does take ownership of the resource should be converted to std unique_ptr e char should be converted to std string but only if the pointer owns the resource e non owning char should be converted to a configurable non owning string reference type string_ref which will also be standardized in a future C standard version A further case which has to be researched is the usage of pointer based arrays where the operators new delete are used as opposed to the single object new delete C 11 provides several new memory management features Move semantics have been introduced as alternative to passing by ref erence respectively copying This new feature enables replacing many uses of references and pointers where move semantics would have been
14. applications and plug ins and can be used with Maven through Tycho 113 E Nomenclature Marker Marks an issue in the editor Maven A build system with dependency managment and a plug in system Move Semantics C 11 feature that models the move of a value rather than a copy or a reference Non owning Pointer A pointer role where the pointer does not owne the resource Null Smart Pointer A smart pointer that doesn t own any pointer OSGi Open Services Gateway initiative a module system for the Java platform Owning Pointer A pointer role where the pointer own the re source POM Project Object Model contains project information for Apache Maven Pointee The object resource a pointer points to Pointer Provides direct access to a memory address on a low level Quick fix Possible solution to an issue like a small refactoring RAIT Resource Acquisition Is Initialization A programming id iom that deals with resource allocation and deallocation Refactoring Altering code without changing its behavior Shared Pointer A smart pointer for shared ownership Smart Pointer simulates a pointer but can reveal pointer role semantics and provide memory management Symbolic execution Analysis of programs by tracking symbolics Target file Allows to specify all required plug in dependencies that a plug in needs to launch 114 Tycho A Maven plug in for building Eclipse RCP applications and plug ins Unique Poin
15. downcasting while still handling errors in the default case case _ For a detailed example how pattern matching was used in the im plementation of the checker using extractor objects see 4 6 4 Exception handling A try catch block has a return value just like any other function It is thus possible to do something like this 1 val ast try 2 val tu ITranslationUnit getTranslationUnitViaEditor marker 3 tu getAST index ITranslationUnit AST_SKIP_INDEXED_HEADERS 4 catch 5 case e CoreException gt e printStackTrace return Because the last value in an expresssion is automatically the return value of the expression ast is automatically assigned with the result of tu getAST if no exception occurs 78 4 6 Scala 4 6 5 Option The Option construct is extensively used throughout the code It allows to transport an optional value similar to boost optional This has the same semantic advantages but the Scala version also provides a some nice syntactic possibilities e None represents an empty option Some a non empty one e Instead of testing the option using an if statement foreach can be used 1 option foreach val gt 2 doSomething val 3 e If the path were the option is emtpy needs to be handled matching is more suitable option match case Some val gt doSomething val 1 2 3 case None gt 4 4 6 6 foreach foreach provides a nice notation to iterate over
16. int x 0 if i 1 x p 1 2 3 4 5 6 if x 7 delete x s else 31 3 Analysis 9 delete p 10 e line 1 p is guaranteed to have ownership of the resource e line 3 if the condition is true x receives ownership of the pointer although that is only clear on line 7 e line 6 only if x was set the condition is true and line 7 is reached otherwise the delete on line 9 is reached resulting in p having ownership e line 7 the delete on x gives the conditional guarantee that x holds ownership e line 9 the delete on p gives the conditional guarantee that p holds ownership The same is of course possible across function boundaries This shows that pointer ownership has to be tracked per code path as the same identifier can have different semantics in different code paths because the underlying pointer can change Note that smart pointers are already used in parts of the code base may also give the required information if a pointer holds ownership or not Other Memory Management Models There are scenarios where the assumption that the first pointer that receives the pointee from the new expression receives the ownership of the object doesn t hold true Consider the following example struct Object 2 Object register 3 void register MemoryManagementUnit register this 32 3 3 Replacing the use of raw pointers 6 Object o new Object We assu
17. it is no longer ref erenced Similar to std shared_ptr lt T gt boost shared_array boost shared_array takes shared ownership of a dynamically allo cated array employing a reference count and deletes it once it is no longer referenced Boost boost shared_ptr class template 26 3 3 Replacing the use of raw pointers boost weak_ptr boost weak_ptr holds a non owning reference to an object managed by a boost shared_ptr Similar to std weak_ptr boost intrusive_ptr boost intrusive_ptr behaves like a boost shared_ptr but external izes the reference count This decreases usability but can be useful if the reference count is for instance embedded in the managed object boost shared_ptr should be preferred whenever possible boost optional See optional 3 3 Replacing the use of raw pointers To replace a raw pointer with a suitable smart pointer or values and references it is first necessary to analyze which roles a raw pointer takes There is no single correct solution for a specific raw pointer as each pointer can take multiple roles and many roles can be rep resented in multiple ways Considering the following use of a raw pointer 1 void set int i 4 2 if i Y 3 xi 3 4 5 Because the referenced value holds no const modifier and a value is assigned the pointer represents a reference The if clause suggests that the parameter is optional it is not clear however if the pointer
18. keeps ownership of the pointer As this is non trivial to detect see 3 3 2 on page 30 it is up to the developer to indicate if the argument is indeed non owning Example 1 void setupCar Car car 2 3 car gt setup 4 6 void setup 7 A 8 Car car new Car 42 9 setupCar car 10 delete car 11 The parameter car of setupCar is non owning as the pointer is never deleted or passed to a function taking ownership The passed object may be modified as long as the object is not const Specific Example e sourcefile DOOM 3 neo tools radiant splines cpp 1728 1750 53 3 Analysis e function idInterpolatedPosition parse e variable src 1 void idInterpolatedPosition parse idParser src 2 idToken token 3 4 src gt ExpectTokenString 5 while 1 X 6 if src gt ExpectAnyToken amp token 7 break 8 9 if token 10 break 11 12 13 if token Icmp startPos 14 src gt ParseiDMatrix 3 startPos ToFloatPtr 15 16 else if token Icmp endPos 17 src gt ParseiDMatrix 3 endPos ToFloatPtr 18 19 else 20 idCameraPosition parseToken token src 21 22 23 The code shows the following characteristics e A raw pointer src is passed as a function argument e assuming parseToken doesn t take ownership of src this func tion never takes ownership of the pointer Example Refactored 54 3
19. pointers and their semantics 3 2 1 The purpose of smart pointers Smart pointers have two primary purposes First the smart pointers that take ownership of a resource also help with the memory management Two main concepts exist the sole ownership of a resource and the shared ownership of a resource Sole ownership means only one smart pointer ever holds ownership of the resource and is thus responsible to release the resource before the smart pointer is destroyed Shared ownership means multiple smart pointers share the ownership of the resource so the resource is only released once the last smart pointer looses it s reference to it Yasskin N3609 string_view a non owning reference to a string revision 3 22 3 2 Available Smart Pointers Second they provide a vocabulary for the developer to express his intents in a way that is not only understandable by humans but also a compiler and other automated tools This makes it easier for a developer who has to understand a piece of code as he doesn t have to guess the roles a pointer has based on how the pointer is used It also enables automated tools to check if the intended usage is not violated 3 2 2 Available smart pointers and other intention revealing constructs The following smart pointers have been considered in this analysis optional is not really a smart pointer but serves a similar purpose in terms of an intention revealing vocabulary It was
20. required Among the new smart pointers one can find std shared_ptr which is a traditional reference counted shared pointer std unique_ptr provides a move only pointer replacing std auto_ptr which i e tried to emulate move semantics using the pre C 11 tools resulting in somewhat unexpected awkward behaviour Upcoming C versions will enhance this further by providing pointers for non owning pointers and non owning string references string_ref as a replacement for char 2 3 Focus Since third party libraries provide similar pointers i e boost the used smart pointer types should be configurable as far as possible This includes factory functions such as make_shared which would have to be adapted accordingly Further the header files for smart pointer definitions must be managed so the conversion can be exe cuted fully automated 2 3 Focus The plug in will be developed in Scala a programming language with functional programming aspects that runs in the Java VM and supports mixing Java and Scala code This is required for working with the Eclipse Plug in Framework Scala was chosen for educa tional purposes and it s pattern matching capabilities which could become useful for processing the abstract syntax tree The project will be developed using Maven as buildsystem and the development will be supported by a bugtracker and a fully auto mated buildserver for continuous integration A project report with managemen
21. this analysis 10 gt project org Qt Project 1 gt project org QObject Trees amp Ownership 33 3 Analysis Conclusion While tracking the ownership of a pointer seems feasible at first conditional ownership transfers and multiple assignments make the task quickly daunting To be able to track the ownership each code path has to be evaluated where the number of codepaths grows exponentially with the number of if statements and potentially un limited with loops and recursion The structural representation of the code provided by an abstract syntac tree allows to track identifiers in the code but not the un derlying value which would be required to be able to track pointers In order to be able to track pointer ownership a codepath analysis would therefore be required An example to highlight the complexity of tracking pointer owner ship would be a list containing pointers Depending on the internal implementation it would be very difficult to track where a pointer enters the list and where it leaves it i e one would have to track the index which the pointer occupies While this is not generally infeasible compilers and advanced code inspection tools can inspect codepaths it is clearly beyond the scope of this project 3 4 Refactoring Cases In order to refactor the use of raw pointers into smart pointers the following section identifies a set of starting points where raw pointers can appear in the source co
22. use of Scala s pattern matching capa bilities Let us consider the following example 1 node match 2 case DeclarationStatement ContainsPointer HasLocalDelete declarationStatment gt placeMarkers ProblemlId localPointerWithLocalDelete node 3 case _ gt node getChildren foreach traverseTree This is a shortened version of Checker traverseTree As we can see node is matched using the match keyword The match statement is similar to a switch statement popular in e g C It allows how ever to match the individual cases using custom extractor objects An extractor object must implement the unapply method 1 def unapply arg T1 Option T2 unapply has one argument and an optional return value A return value of None indicates that the extractor object does not match where a return value of Some indicates that it matches Further is the type of the argument evaluated if it matches the matched expression For instance this is how the DeclarationStatement extractor is im plemented 67 4 Implementation 1 object DeclarationStatement 2 def unapply parameter IASTSimpleDeclaration Some parameter This extractor matches only if the argument is of type IASTSimpleDeclaration but it returns the argument unconditionally Extractor objects allow for great flexibility because they can be nested 1 node match 2 case DeclarationStatement ContainsPointer HasLocalDelete declarationStatment gt pl
23. with collection classes the use of JavaConversions from Scala was benefical 1 import collection JavaConversions _ 2 val includePaths includeOption getIncludePaths toSeq includePath 80 4 6 Scala The snippet shows how implicit conversions for Java are imported includeOption is a reference to an instance of IOption a Java inter face provided by the eclipse framework After the import statement Scala is able to implicitly convert Java collections into Scala and vice versa This way we didn t have to clutter the source code with type conversions 4 6 9 Conclusion Overall the use of Scala in this project has been a great experi ence We gained many insights into different programming patterns than what we are used to from C and Java and the integration between Java and Scala was smooth Especially the pattern matching helped to write code that is concise reliable and easy to extend While not all things are very intuitive e g how Maps are handled there were no insurmountable Prob lems and it was overall a pleasure to use Because we were new to Scala it certainly slowed us down in the beginning but we think this learning experience payed off We can clearly recommend Scala for Eclipse plugins as we did face any Scala related issues and the resulting code was an improvement on what we could have done using Java 81 5 Conclusion This chapter reviews the results of our work and gives an outlook how p
24. 3 Known Issues preferences It also removes delete statements and uses the get function of a smart pointer if needed D 3 Known Issues The plug in only operates as part of eclipes code analysis To man ually trigger the analysis process right click on a file in the Project Explorer and select Run C C Code Analysis The functionality to convert pointers is limited by the cases men tioned in the Analysis section of this thesis 111 E Nomenclature AST Abstract syntax tree represents the source code as tree data structure Best Practice A method or technique that yields results superior those achieved with other means Callee The callee is the function that is being called Caller The caller is the code that calls this function Checker Responsible for placing markers Codan Eclipse s static code analysis project Coding Convention A set of guidelines that recommend a pro gramming style Dangling Pointer A pointer that does not point to a valid object Eclipse RCP A platform for building rich client applications Empty Smart Pointer A smart pointer that points to no object shall not be dereferenced Indentifier An identifier in the source code e g in int x is x the identifier Intention Revealing Language Construct Language con structs such as references boost optional or smart pointers JVM Java Virtual Machine Manifest file Contains project information for building Eclipse RCP
25. 5 04 8 be ea eee ate A 84 5 3 Personal Statements 84 5 3 1 Andr Fr hlich sois se e a 84 5 3 2 Christian Mollekopfl 86 89 A l Approach 24 4 Ae ee Oe eR eee eee 89 ee eons 90 aaa 90 uae whee ee Eee 91 Le sae ee a a ee a 92 B Environment 93 BI Tool he Se SoS AS Oe ee a 93 a e e a 94 ea aa e ar Me 94 B 2 2 Eclipse Plug in Development Environment 95 ebene de 95 AER 95 o 95 B 2 6 IFS CDT Testing o ocres 96 DIT N cado e aa aa 96 Mi as dra ee ea A 98 TOEO 98 ie be dao 99 CE sos cors ae wp an ek BS Be Be a N 102 ree 102 eee a AA ee ee ee O 103 a eee O 104 B 6 3 Jenkins es cris res ee era 104 105 Pal a a 105 C 2 Installing the Eclipse IDE 105 A a A we ee 106 Contents CA Importing the project u u 48 44484 24 55 Lee A PR eee ae Aes C 5 1 Manifest and plugin xml C 5 2 Target A C 5 3 Markers 22 oo oo nn Coe Quick API BSS ES D User Manual D 1 Installation 2 2 2 Ho nn D 2 Guide 2 22 2 oo oo nn D 3 Known Issuesl 2 2 2 o E Nomenclature F Bibliography 1 Introduction At the University of Applied Sciences Rapperswil a bachelor thesis is usually done by groups of two students This chapter covers the project duration the contents of this report and its target audi ence 1 1 Project Duration This project started with the beginning of the spring term 2013 on February 18th The kickoff meet
26. ASTEqualslnitializer Initializer with equals sign IAS TInitializerList Braced initializer list Example This example gives you a basic understanding how the abstract syn tax tree in Eclipse works The declaration is compound a simple declaration specifier containing the data type and a declarator con taining all the other details It is itself compound of multiple ele ments one for the pointer one for the name and one for the equals initializer You can imagine this works somehow like a russian ma tryoshka doll With the Scala match expression we do the pattern matching to navigate through the abstract syntax tree 1 int x new int 1 The code line above shows a simple statement written in C The tree below shows how this code is stored internaly 100 B 4 Eclipse Abstract Syntax Tree int x int 1 ICPPASTSimpleDeclSpecifier ICCPASTLiteralExpression ICCPAST Typeld ICPPASTInitializerList ICPPASTNewExpression ICPPASTSimpleDeclSpecifier ICPPASTDeclarator IASTPointer IASTName IASTEqualsInitializer IASTSimpleDeclaration The names are rather long because of the vast amount of available interfaces With some basic knowledge of C it is not too diffi cult to understand what interface represents what part of the code However the AST DOM view is very handy to find the appropriate interface A AI bin DOM AST X 316 B v E ICPPASTTranslationUnit v ICPPASTFunction
27. Definition fl Y ICPPASTSimpleDeciSpecifier void v a ICPPASTFunctionDeclarator JIASTName fl vw JASTCompoundStatement w IASTDeclarationStatement v 3 IASTSimpleDeclaration x Y ICPPASTSimpleDeciSpecifier int v a ICPPASTDeclarator lASTImplicitNameOwner a gt ASTPointer JIASTName x a lASTEqualslnitializer v3 ICPPASTNewExpression v ICPPASTTypeld Y ICPPASTSimpleDeclSpecifier int a ICPPASTInitializerList ICPPASTLiteralExpression 1 Figure B 4 The DOM AST View If the view is not visible initially you can use the Show View Dialog under Window Show View Other to get it Clicking on a node highlights the correspondent part of the code 101 B Environment B 5 Testing Automated testing with JUnit is possible by extending the Check erTestCase class It provides an interface to load code and run a checker over it 1 def testLocalRawPointer Unit 2 loadCodeAndRunCpp void foo int x new int 3 delete x 3 checkErrorLine 1 Errorld 4 For Java developers the test facility provides with getAboveComment a way to load C code from the comment above the test method which is particularly usefull for larger code snippets with multiple lines Since the Eclipse test facility is written for Java develop ers the getAboveComment Method doesn t work for our Scala test classes Fortunately this is also not necessary since Scala supports multi line strings 1 d
28. Figure B 1 The Eclipse dialog to install new software B 2 Eclipse Plug ins The figure shows the Eclipse dialog to install new software Under Work with the default Juno update site is selected The screen shot also shows how to use the search field While using the search field it may happen that Eclipse responds slowly This dialog can also be used to install software from other update sites Ether the address can be entered directly or may be managed using the Add button B 2 2 Eclipse Plug in Development Environment If you don t use the Eclipse RCP package you need to install this plug in to get the environment for developming Eclipse plug ins B 2 3 Scala IDE for Eclipse The Scala IDE for Eclipse is a powerful plug in providing a complete IDE to develop in Scala The update site for Eclipse Juno is http download scala ide org sdk e38 scala210 stable site B 2 4 C C Development Tools You don t have to install this plug in into your plug in development Eclipse instance but it may be convenient If it isn t installed it can be provided using a target file B 2 5 Jeeeyul s Eclipse Themes Chrome Originally this plug in is designed to make Eclipse Juno more beau tiful As it often happens during the development of Eclipse plug ins that more then one Eclipse instance is running we use this plug in to give each instance a different appearance 95 B Environment It can be installed u
29. Whether or not the header should be copied from the ones distributed with the plug in e The initializer expressions e g std make_unique Note that two initializer expressions are available getInitializerExpression O and getEqualInitializerExpression These are required because direct initialization getInitializerExpression usually only re quires the pointer where an an assignement getEqualInitializerExpression O requires the pointer to be wrapped with the constructor call or e g a std make_unique due to the explicit constructor The SmartPointerDefinition instances are created using the SmartPointerFactory which provides a place to switch between various smart pointers std Boost Qt So far only the Standard C Library version has been implemented though 4 2 2 Control Flow The primary entry point for the quickfix is the QuickFix modifyAST index IIndex marker IMarker method which is called by the framework when the quickfix is activated modifyAST employs the template method patter in order to centralize most logic in the base classes and only deferring the particualrities to the subclasses The template method operations are e getTargetStatement node IASTNode Retrieves the primary target statement that should be refactored This is required because the quickfixes operate on different targets such as local variables parameters and return values Based on the primary target statement furt
30. a dec laration in a for loop to the beginning of the function for int i 0 i lt 3 i MyClass const p new MyClass becomes for int i 0 i lt 3 i std unique_ptr lt const MyClass gt p new MyClass aa PF wn KB When creating smart pointers type hierarchies must be taken into account i e the type used in the new expression must be used to to create the smart pointer as opposed to the type of the pointer variable declaration that might be using a base type 1 Base p new Derived 2 becomes 3 std unique_ptr lt Base gt p 1 new Derived 3 3 4 Refactoring Cases 3 4 1 Format The section 3 4 3 on page 39 first analyses the particularities of the chosen starting points wherer a raw pointer could be used in the source code 3 4 4 on page 42 then analyses an example of each starting point for the case where the pointer holds ownership and once for the case where the pointer doesn t hold ownership Each case is analysed using the following format e A short explanation e A generic example based on Listing 3 1 e A specific example from a real world code basd e The refactored generic example e Limitations and edge cases of the handling of the refactoring case This format allows to describe all considered cases with enough de tail that the implementation can be based on it Throughout the examples the following class hierarchy is used class Vehicle 1 2
31. a integrates seamlessly with java as Scala can call java code and java can call Scala code We were thus able to write our project fully in Scala although the base classes we had to extend and the whole eclipse framework are pure java code This works because Scala code compiles to bytecode for the JVM just like normal java code 4 6 2 val var Scala allows to specify identifiers as either val or var var is a normal variable which can be reassigned and changed as we re used to from e g Java val is an immuatble variable which cannot be reassigned while the value remains mutable var vi MyType new MyType vi new MyType valid val v2 MyType new MyType v2 new MyType invalid v2 modify valid ar e N By trying to avoid var and using val whereever possible it be comes much easier to track variables Note how this effectively re moves the problem of identifiers changing semantics as described in Section 3 3 2 on page 34 scala lang org A Tour of Scala 77 4 Implementation 4 6 3 Pattern Matching The pattern matching supported by Scala s match keyword is a great feature that is applicable in a lot of cases and was used throughout the codebase A nice example is down casting of values x match 4 1 2 case name IASTName gt doSomething 3 case node IASTNode gt doSomething 4 case _ gt println Not a name nor a node 5 This notation provides a concise and extensible way to
32. a pointer is normally see page 32 guaranteed to be owning e When a pointer is first initialized using new e When a pointer is finally deleted using delete In all other cases a pointer is potentially non owning and the only way to determine the ownership of a pointer is to track it from either the allocation or the deletion 30 3 3 Replacing the use of raw pointers Between allocation and deletion the pointer may be passed around potentially transferring ownership to other variables Each assign ment may potentially transfer ownership e An assignment to a variable int x p e An assignment to a function parameter foo p e An assignment to a return value return p However while an assignment may transfer ownership it is not guar anteed to do so The assignment may instead result in a non owning reference Consider the following example 1 int p new int 2 int x p 3 foo p 4 delete x e line 1 p is guaranteed to have ownership of the resource e line 2 x MAY receive ownership of the resource but is not guaranteed to do so From this point on it is unclear if x or p has ownership of the resource or is just a reference e line 3 as in line 2 foo MAY receive ownership but is not guaranteed to do so e line 4 the delete on x gives the guarantee that x holds ownership It is also possible that a pointer looses or receives ownership of a pointer conditionally int p new int
33. a rough guide helping ous to determine our next steps every week A 2 1 Intended Plan Spring Term 2013 9 10 11 12 13 14 15 16 1 213 4 5 6 7 8 Kick off Non owning ptrs E Local scoped ptrs Char support E Function arguments Functions returns Functions returns Poster video manual Spare Delivery 90 A 2 Project Plan Of course we couldn t follow the plan as there are many unexpected outcomes during the development With the weekly meetings we could flexible change our course and still having a direction The plan shows we falsely assumed this semester had fourteen weeks as usual but actually it had fifteen weeks A 2 2 Actual Plan Spring Term 2013 1 12 3 4 5 6 7 8 9 10 11 12 1314 15 16 17 Kick off Local Ptrs E Return Values E a Non owning Ptr L Argument Parameter Ptrs Revision At the beginning we have used more time because we had prob lems with the build system and also worked out our objectives In addition we had little experience with Scala In the second last meeting we realized that we did not understand our task as we should We falsely assumed that smart pointers are primarily a better way for memory management
34. aceMarkers Problemld localPointerWithLocalDelete node node is first matched using DeclarationStatement where node matches if DeclarationStatement unapply returns an Option that is not None If DeclarationStatement matches its return value is passed on to the next extractor object ContainsPointer If all extractor objects match the final return value is available in delarationStatement which can then be used inside the case in this case to place a marker A more advanced example than the DeclarationStatement is the ContainsPointer extractor that recusively searches for a node of the type IASTPointer 1 object ContainsPointer 2 def unapply node IASTNode Option IASTNode 3 node getChildren foreach child gt 4 child match 5 case x IASTPointer gt return Some node 6 case x IASTNode gt unapply x foreach ret gt return Some ret 7 case _ gt 8 9 68 4 2 Quickfix Its unapply method uses itself pattern matching to identify the type of its children and calls itself recursively to descend in the tree of children Because this extractor object can also not apply althought the argument type matched it is possible that unapply O returns None instead of Some Note the shorter notation used to match a type 1 case x IASTPointer gt return Some node This allows to directly match for a type without writing a dedicated extractor object but has the drawback that no extractor objec
35. age of the test project and extends the CheckerTestCase class and is a JUnit test case C 5 4 Quick fixes The framework also provides a facility to provide quick fixes for markers Activating these gives an user the opportunity to trans form the reported problem The entry point for quick fixes is the the QuickFix class located in the ch hsr ifs cdt smartor quickfix package The package also contains subclasses providing the different quick fix functionality for each case 108 D User Manual This chapter shows the installation process of the Smartor plug in how it is used and its known issues It is assumed that the reader is familar with using Eclipse D 1 Installation The following steps guides you through the installation process 1 Start Eclipse 2 Select Help gt Install New Software 3 Type or paste the URL of the update site into Work with 4 Enable the checkbox to select the plug in 5 Click the finish button D 2 Guide The plug in is active after the installation While writing C files markers are triggered by the use of raw pointers The occurrence gets a yellow underline and on the left side of the editor a icon is placed to indicate the issue It is possible to resolve the issue manually or the activate a quickfix using the icon in the editor or using a shortcut usually Strg 1 or Cmd 1 on Mac 109 D User Manual _ C C Demo main cpp Eclipse Platform m es gt
36. alRawPointer 13 name Smartor 14 messagePattern Smartor amp apos amp apos 0 amp apos amp apos gt 15 lt problem gt 16 lt checker gt 17 lt extension gt Each problem has an id which is used by the checker s reportProblem method Each quickfix can then be registered to such an id using the problemId attribute in plugin xml 1 lt extension 2 point org eclipse cdt codan ui codanMarkerResolution gt 3 lt resolution 4 class ch hsr ifs cdt smartor quickfix ConvertToUniquePtr problemId ch hsr ifs cdt smartor plugin error localRawPointer gt lt resolution gt 7 lt extension gt al o If the checker now reports a problem the associated quickfixes are offered to the user Further can all problems individually be turned on or off in the configuration 4 4 Tests The project was developed using a test driven approach Therefore a set of JUnit testcases has been implemented All tests are in a separate project ch hsr ifs smartor test to avoid dependencies of 75 4 Implementation the main plug in on the test infrastructure The tests have been written in Scala and reuse the test infrastructre of codan Because each test class can only test one quickfix one test per quick fix had to be implemented 4 5 Review Unfortunately we were not able to implement all analysed features before end of the project However most of the more difficult prob lems such as node traversal
37. and finding callers of functions have been solved To document missing parts unittests have been written for all miss ing features Note that the ExtractRawPointer and ExtractRawPointerAll refactor ings are no longer required because the raw pointer is now auto matically extracted during the smart pointer refactorings Instead a refactoring for owning smart pointers to transform the call to get to release would be required For this ExtractRawPointer and the corresponding check in the checker can serve as basis The code is otherwise well structured easy to extend and work with and should thus be a good starting point for further work The ar chitecture was designed primarily to share logic among similar quick fixes Flexibility has been introduced where required e g by encap sulating the smart pointer knowledge in SmartPointerDefinition 4 6 Scala The plug in was written completely in Scala as a learning experience and to make use of Scala features such as the pattern matching which we hoped to be useful when analyzing the AST 76 4 6 Scala Scala is a programming language that runs in the JVM is fully object oriented supports aspects of functional programming and has a focus on a concise syntax For an introducation to Scala A Tour Of Scala can be recommended This section is going to highlight a couple of features that were found to be particularly useful 4 6 1 Seamless integration with Java Scal
38. as raw pointers in C and built our analysis on that assumption In the last two weaks our main focus was to revise our work 91 A Organisation A 3 Time Report Target o Frohlich Mollekopf Figure A 1 Time spent per week The figure shows how much hours we spent working on this project per week Time shortfalls due to illness or vacation were compen sated over the whole project duration The effort for this module should correspond to 12 ECTS credit points or 360 hours of work The total time spent on this thesis per person e Andr Frohlich 404 hours e Christian Mollekopf 405 hours These numbers include an estimation of the effort that was done after the print of this thesis 92 B Environment Creating Eclipse plug ins is a complex task This chapter gives an overview about the tools used in this project It also severs as a brief introduction to the relevant areas of the Eclipse framework B 1 Tools e Eclipse C C Development Tooling is a project based on the Eclipse plattform which provides a fully functional C and C integrated development environment e Eclipse is a software development environment with an ex tensible plug in system e Git is a distributed source code management system e Jenkins is an open source continous integration server e Maven is a build manager for Java projects e Redmine a web application for project management e Tycho is set of Maven plug ins and exte
39. ask Many of these transformations are non trivial and require a careful analysis The main focus is the anlysis of possible pointer roles and their relation with newer C smart pointers Usually Eclipse plug ins are written in Java For this thesis we decided to examine how the Scala programming language helps to write such a plug in as it provides a build in pattern matching mech anism Using Scala we hoped to be able to write cleaner and less cluttered code without the usual boiler plate Java requires In ad dition we wanted to expand our knowledge with the functional pro grammming paradigm Scala uses Results Our plug in assists a developer to convert raw pointers into smart pointers It is able to find occurrences and mark them in the editor using a marker The plug in also provides a quick fix for various cases Activating a quick fix transforms the code to get rid of the raw pointer and replaces it with the appropriate smart pointer 2 The plug in is also able to detect and remove local deallocation code as it becomes invalid using a smart pointer 1 int x new int 1 2 delete x Listing 1 Before the transformation 1 int x std unique_ptr new x 1 Listing 2 After the transofrmation IV MA A _Resource Demo src ast cpp Eclipse Platform val a Bastcpp x Ee amp include lt memory gt a void f1 e s int x new int 1 om a dele Convert to exempt_ptr Probl
40. assigned of course References typically occur as return values function parameters and local identifiers C offers a dedicated operator for references 1 void foo int amp ref 2 int i ref 3 gt By using the reference operator it is clear that ref can not be NULL doesn t own the referenced resource and that the reference can not be reassigned Note that a reference can become dangling if the reference lives longer than the resource it is pointing to 1 int amp getLocalVariable 4 2 int x 3 return x a y While this is an obvious example to illustrate the problem valid scenarios exist where a reference can become dangling However in such cases the use of a C Reference is not suitable and other options such as a std weak_ptr should be considered Reassignable reference Since references cannot be reassigned with a new pointee and must be initialized immediately it is not always possible to use a C reference in place of a raw pointer when the pointer has the role of a reference 1 int ref getRef 2 for int i 0 i lt 3 i f 3 if condition i 15 3 Analysis 4 ref getRef i 5 6 ref getNewValue ref is initialized with the reference to different values based on condition Because references must be initialized immediately and may not be assigned a new value later on it is not possible to simply replace the use of the pointer with a reference In such cases n
41. d to a std unique_ptr destroyCar could be removed entirely in this case since it s apart from the delete empty car in foo must be wrapped by a std unique_ptr If car in foo would already be a std unique_ptr std move would be required to pass it to trySellCar using move semantics 1 void foo 2 3 std unique_ptr lt Car gt car new Car 42 4 trySellCar std move car 5 Limitations and Edge Cases e The same limitations as for a local pointer apply as the pa rameter behaves inside the scope of the function like a local variable e If the refactored function is either virtual or has overloaded functions the workaround described in 3 4 3 on page 39 should be applied as migration path e If a caller already uses a std unique_ptr but extracts the raw pointer using release the pointer can be moved using std move instead void bar non_owning_ptr lt Vehicle gt std unique_ptr lt Car gt p bar p release becomes 1 2 3 4 5 6 7 bar std move p 92 3 4 Refactoring Cases 3 4 8 Function parameter Non owning pointer A non owning pointer can be passed to a function as argument for example to e provide a reference to a data structure where complex return values can be stored e pass a dynamically allocated object as argument The pointer parameter is non owning if e it was ensured that the pointer is not owning see page 50 e it was ensured that the caller
42. de and analyses what refactorings can be applied to each starting point Raw pointers can appear in various places and convey various se mantics Each starting point where a raw pointer could appear is associated with a number of possible refactorings one per smart pointer which are then offered to the developer Because we are not able to analyze the semantics automatically see Section 3 3 2 34 3 4 Refactoring Cases it is up to the developer to choose a suitable refactoring from the options provided It is however possible to support the developer in his choice by limiting the available refactorings using heuristics As the complexity for what pointers can be used can quickly go be yond what we can reasonably refactor in a way that is still useful this analysis tries to identify a limited set of the common cases so we can provide actually useful refactorings This means not every possible case is covered but a limited set of cases should be handled well By looking at concrete cases that are existing in real world codebases we hope to identify a useful subset of possible refactor ings Further is the complexity limited by only refactoring a single call hierarchy level instead of recursively converting full call hierarchies This is because tracking the variables is not directly supported see also Section 3 3 2 on the preceding page so the task would be too complex within the scope of this project Further has this app
43. ded up being a bit strenuous but still proved to be a great learning experience Unfortunately we couldn t get everything to the state where we would have liked it but I think we still laid a foundation that a future project could build upon 88 A Organisation Every software development project has to have some sort of organ isation This chapter gives an overview on the approach we used and how the project was planed It shows how the plan actually turned out A 1 Approach The regulation of our school limits the time we can and should spent on this project Therefore the scope of our project has to be open Much of the organisation is specified by the supervisor of the thesis Prof Sommerlad favored weekly meetings in which the next steps as well the previous are discussed Once a week usually on monday afternoon we met with profes sor Sommerlad and his assistant in the working room of the Institue for Software at the University of Applied Sciences Rapperswil On the agenda is to tell him what happend in the past week discuss open problems and agree on the next steps This leads to an incre mental software development approach For collaboration we decided to use Redmine It provides support for issue tracking displaying gantt charts document management and a project wiki 89 A Organisation A 2 Project Plan Although the next steps are discussed week by week we created a project plan first It serves as
44. e The initialization for the pointer may also occur at a later stage no direct initialization In this case both the definition of the pointer and the initialization must be adjusted accordingly e If a pointer is deleted early before it goes out of scope it is required to reset the smart pointer early using unique_ptr lt T gt reset nullptr in order not to change the lifetime of the pointee e If the pointer is reassigned the smart pointer would have to be reassigned as well using its reset method Note that the old pointer must be released first in order not to delete it 1 std unique_ptr lt const Vehicle gt p new Car 42 2 p release 3 p reset new Car 42 But since this code would result in the first assigned pointer to leak the only valid scenario would be 45 3 Analysis 46 1 std unique_ptr lt const Vehicle gt p new Car 42 2 passOwnership p release 3 p reset new Car 42 There must be something which takes ownership of the old pointer otherwise to code is not valid If passOwnership would expect a std unique_ptr as argument as it should this would result in passOwnership make_unique p release At this point it should become evident that it is not a good idea to reuse the pointer identifier when using an owning pointer The plugin therefore does not handle this case If a function parameter to which the pointer is passed already uses a std unique_ptr the poin
45. e appropriate choice As a special case a delete within the local scope can be used as heuristic to determine that the deleted raw pointer holds ownership of the resource In this case it is not necessary to offer the non owning pointer refactoring to the develeoper 42 3 4 Refactoring Cases 3 4 5 Local pointer owning pointer A local pointer receives ownership if it is initialized using a new expression a function returning an owning pointer i e a factory function or an owning pointer variable The owning pointer must either pass ownership somewhere or delete the resource before it goes out of scope Example 1 void foo 2 3 Vehicle const p new SpecializedCar lt Engine gt 42 4 bar p 5 delete p 6 e The pointer has a const modifier that must be preserved during conversion e The initialization expression of the allocated object is 42 e The pointer is then passed to bar which will result in an error after converting p to a smart pointer e Finally the object is deleted at the end of the scope resulting in exactly the same behaviour when using a smart pointer Specific Example e sourcefile DOOM 3 neo tools radiant splines cpp 1307 1323 e function idCameraDef load e variable src 43 3 Analysis 1 bool idCameraDef load const char filename 2 idParser src 3 src new idParser filename LEXFL_NOSTRINGCONCAT LEXFL_NOSTRINGESCAPECHARS LEXFL_ALLOWPATHNAMES 4
46. e checkers which per form real time analysis on the codd 1Eclipsepedia CDT designs StaticAnalysis 98 B 4 Eclipse Abstract Syntax Tree B 4 Eclipse Abstract Syntax Tree An abstract syntax Tree AST represents the syntactic structure of source code Eclipse CDT provides an interface to its internal syntax tree data structure allowing plug in developers to parse and manipulate the source code Interface Eclipse provides a rich set of Java interfaces to access its abstract syntax tree The following list is a selection and should give you an overview of the fundamental interface we used for the project IASTNode Root node of the abstract syntax tree IASTAttributeOwner AST node with attributes 1IASTDeclarator Base interface for a declarator IASTSimpleDeclaration Simple declaration IASTStatement Root node for statements IASTCaseStatement case statement IASTCompoundStatement A block of statements IASTDeclarationStatement Statment for declara tion IASTDoStatement do statement IASTExpressionStatement Expression statement IASTForStatement for statement IASTIfStatement if statement IASTReturnStatement return statement IASTSwitchStatement switch statement Wikipedia Abstract Syntax Tree 99 B Environment IASTWhileStatement while statement ASTDeclaration Root node for declaration IASTFunctionDefinition Function declaration IASTSimpleDeclaration Simple declaration IASTInitializer Initializer for a declarator I
47. e p is initialized using a call to getReference which returns a non owning pointer e pis then passed to bar which will result in an error after converting to a smart pointer 47 3 Analysis Specific Example e sourcefile DOOM 3 neo tools radiant CamWnd cpp 53 67 e function ValidateAxialPoints e variable selFace 10 11 12 13 14 void ValidateAxialPoints int faceCount g_ptrSelectedFaces GetSize if faceCount gt 0 face_t selFace reinterpret_cast lt face_t gt g_ptrSelectedFaces GetAt 0 if g_axialAnchor gt selFace gt face_winding gt GetNumPoints g_axialAnchor 0 if g_axialDest gt selFace gt face_winding gt GetNumPoints 4 g_axialDest 0 else g_axialDest 0 g_axialAnchor 0 The code shows the following characteristics 48 The definition of selFace is nested in an if clause selFace is initialized with a reference to a face_t object Because selFace is neither passed to a function nor is it deleted in ValidateAxialPoints it is ensured that selFace doesn t hold ownership 3 4 Refactoring Cases Example refactored void bar Vehicle const dE 2 Vehicle getReference 3 4 void foo s 1 6 non_owning_ptr lt const Vehicle gt p getReference 7 bar p get O 8 The pointer can be refactored to a non_owning_ptr Because p is passed to bar the raw pointer must be extracted using p get In ca
48. ect It be haves exactly like a raw pointer and doesn t provide any memory management facilities It s sole purpose is to express that the pointer doesn t hold ownership of the resource non_owning_ptr should be created using make_nonowning The pointer is drafted in N35147 as exempt_ptr with the associated function make_exempt 3 2 8 optional optional allows to transport an optional payload value reference The payload is accessed using the familiar operators from point ers to dereference it and gt to access a member of the contained object directly optional is not yet standardized but should be part of a future version of the C standard 25 3 Analysis 3 2 9 boost smart pointers Boost is a widely used set of libraries that provide its own set of smart pointers Some standard smart pointers such as std shared_ptr came out of boost initiallyP boost scoped_ptr boost scoped_ptr takes sole ownership of a resource and deletes it upon destruction It is non copyable and doesn t support move semantics Similar to std unique_ptr lt T gt boost scoped_array boost scoped_array takes sole ownership ofa dynamically allocated array and deletes it upon destruction It is non copyable and doesn t support move semantics Similar to std unique_ptr lt T gt boost shared_ptr boost shared_ptr takes shared ownership of a resource employing a reference count and deletes the resource once
49. edge of Scala is immense and the possibility to get his help was very useful I was able to develop a better sense for func tions without side effects and the use of constant variables Scala also helps to write clearer less bloated code I can imagine using Scala instead of Java for future projects During the project we had often problems with our build system using Maven and Tycho It was not always easy to solve the prob lem and it took a lot of time that we would have better used for something else In the second last meeting two weeks before the end of the project we found out that we did not understand our task as we should For me this was a very frustrating experience We falsely assumed that smart pointers are primarily a better way for memory management as raw pointers in C We knew that it is possible to demonstrate the semantic meaning of pointers as we also analyzed the various pointer roles However we have failed to understand that the roles should be used as the starting point for our analysis Of course we have the remaining time as good as possible in order to correct our mistake Finally the project was pretty exhausting but I was able to learn a lot The topic is very interesting and the Scala a language was enrichment both for the project as well as for my experience 85 5 Conclusion 5 3 2 Christian Mollekopf As our second project using eclipse as a platform and maven as buildsystem it was somewhat fr
50. ef testLocalRawTwoDelete Unit 2 loadCodeAndRunCpp 3 void foo 4 4 int y 5 delete y 6 int x new int 3 7 delete x s youn 9 checkErrorLine 2 Errorld 10 B 6 Build System and Continous Integration Building Eclipse plug ins may be a complex and difficult task We have opted for the more modern approach using Maven To do con tinous integration we decided to use Jenkins which regularly build the Maven project 102 B 6 Build System and Continous Integration B 6 1 Tycho There two main approaches to build Eclipse plug ins Apache Ant with PDE and Apache Maven with Tycho We used the more mod ern build technqiue using Maven and Tycho Maven Tycho is a set of Maven plugins There is no installation required as Maven automaticaly download the plugin the first time it needs it Normally all building information is in the Maven POM file How ever Eclipse RCP application and plug ins are using a manifest file for that Tycho is able to sychronize these two approachs bringing both together To do so it extends the maven dependency model Many eclpse artifacts are not stored in maven repositories but in p2 repositories instead With Tycho Maven is able to use these p2 repositories to solve building dependencies Tycho is using a manifest first approach Metadata All Maven configuration data is stored in the pom xml file Meta data may be distributed over several files e bundle manifes
51. em description Smartor ConvertToSharedPtr LocalPointerWithLocalDelete ConvertToUniquePtr A ooo Resource Demo src ast cpp Eclipse Platform a Bastcpp x TEE b include lt memory gt a El void f1 e ES std unique_ptr lt int gt x new int 1 om Writable Smart Insert 4 5 Conversion into a unique pointer Further Work Pointers to strings and arrays are special cases and would be an interesting subject for further studies and a useful extension for the plug in The heuristic to determine ownership can also be extended and would be a valueable addition Furthermore pointer tracking using symbolic execution could be greatly beneficial Declaration of Authorship We declare that this thesis and the work presented in it was done by our own and without any assistance execept what was agreed with the supervisor All consulted sources are clearly mentioned and cited correctly No copyright protected materials are unauthorizedly used in this work Place and date Andr Frohlich Place and date Christian Mollekopf VII Contents 5 She ia ee eee oe E 5 eee ee ee ee 3 5 ee Ce eee ae ce ee ae 6 7 e E A AA pee T E E EE E E E E E ee T IA s os eror mak OR Ak a ne e r a od 9 2 4 Agreement ooa AA AA 11 13 3 1 Pointer Roles 205 228 a 13 3 2 Available Smart Pointersl 22 3 2 1 The purpose of smart pointersl 22 3 2 2 Available smart pointers
52. emented using smart pointers 1 void foo non_owning_ptr lt int gt value 2 if value 3 int i value 4 s An optional reference or value can be represented by a non_owning_ptr value can be empty indicating that the value is not available Note that this notation doesn t give any explicit information that value may be empty Also note that this example passes value by reference like the first example 18 3 1 Pointer Roles Error Code Since an integer can be assigned to a pointer variable the pointer can be misused to transport other information instead of the address of a pointee Besides optional values this property is typically used for return values where pointers are mixed with error codes In its simplest variation the only error code is NULL where NULL would be more appropriately represented by nullptr in C 11 1 int foo 2 int i getValue 3 if error 4 4 return 0 5 6 return i 7 While this example looks similar to an optional return value its se mantics are slightly different An optional return value implies that it is entierly valid that no value is returned where an error code such as nullptr implies that the call to foo should normally suc ceed but may fail In such cases an exception based error handling may be better suited clearly distinguishing the normal operation and the error handling code path More advanced versions of such error codes may transport di
53. emory leak if the caller doesn t handle the return value is fixed 10 2 4 Agreement 2 4 Agreement The following parties confirm the validity of the tasks described in this chapter Place and date Prof Peter Sommerlad Place and date Andr Frohlich Place and date Christian Mollekopf 11 3 Analysis This chapter analyses available smart pointers and their applicabil ity to various scenarios where raw pointers may be used The first section introduces the problem domain by analyzing the various roles a pointer can take and how a raw pointer could be better represented using smart pointers and other language con structs The second section presents a set of common smart pointers that are currently available and explains their typical usage The third section analyses how suitable smart pointers for a raw pointer could be chosen and describes an approach to automatically select a smart pointer based on the ownership of the raw pointer Finally the fourth section analyses a set of concrete code examples and how they could be refactored This analysis is then meant to serve as foundation for the implementation 3 1 Pointer Roles Considering the following pointer declaration 1 T xp A raw pointer can have a variety of roles but gives no indication which roles the author of the code intended for it It is thus left to the reader of the code to figure out what the author s intentions were W
54. er evaluating other factors such as the projects coding conventions or other best practices 3 3 1 Choosing the right smart pointer for a refactoring Because a raw pointer can be represented by various combinations of smart pointers and other intention revealing language constructs reference value the problem can be simplified by selecting a subset of smart pointers to implement the roles When looking at the options for suitable smart pointers there are two primary candidates with which most roles can be expressed non_owning_ptr and std ungiue_ptr std shared_ptr is usually not an option because there is no reason why a reference count should be required if there wasn t one with the raw pointer If there was a custom reference counting with the raw pointer a refactoring would need to be able to correctly identify and remove it std shared_ptr could still be a useful offer in some cases such as a new factory function that hasn t been used yet if it is already used we run into the aforementioned problem that a reference count is introduced where there wasn t one before optional is not required as its functionality can be emulated using empty smart pointers A refactoring without optional is syntacti cally also less intrusive the smart pointer can be used exactly like a raw pointer optional requires additional adjustments C References are also implementable using non_owning_ptr Fur ther is non_owning_ptr
55. ething like the singleton pattern The important difference is that getVehicle doesn t transfer the ownership of car but only returns a reference to it Specific Example e sourcefile DOOM 3 neo tools radiant splines cpp 1606 1612 e function idInterpolatedPosition getPoint e variable startPos endPos 1 idVec3 idInterpolatedPosition getPoint int index 2 assert index gt 0 amp amp index lt 2 3 if index 0 4 return amp startPos 5 6 return amp endPos ane The code shows the following characteristics e The if clause results in two possible code paths of which both return a non owning pointer Example Refactored non_owning_ptr lt Vehicle gt getVehicle 1 2 3 static Car car 4 return make_nonowning amp car 5 6 7 void main 58 3 4 Refactoring Cases s 1 9 Vehicle vehicle getVehicle get 10 y The return value can be refactored to a non_owning_ptr to indicate that no ownership is transferred to the caller Each return statement must be adjusted to use make_nonowning Each caller must be adjusted to extract the raw pointer using get O Limitations and Edge Cases e If a caller already uses a non_owning_ptr it can be initialized directly instead 1 non_owning_ptr lt Vehicle gt vehiclet getVehicle 7 3 4 11 Heuristic to determine ownership local delete If a delete is available within the local scope it can be assumed that the pointer
56. fferent error codes using the pointer variable 1 define ERROR_FOO_FAILED 1 2 define ERROR_FOO2_FAILED 2 3 int foo 4 int i getValue 5 if error 4 6 return ERROR_FOO_FAILED 7 8 return i 9 As this usage is a clear misuse of pointers this pointer role is not considered further by this analysis 19 3 Analysis Array C arrays degrade to raw pointers when assigned to a raw pointer variable e g when passed to a function with a raw pointer parame ter Hence a raw pointer can have the role of an array 1 int getFirst int array 1 2 return array 0 3 An array degrades to a pointer because the identifier of an array is equal to a pointer pointing to the first element of the array i e array amp array 0 Note however that array contains no indica tion that it is an array and further doesn t convey any information about its size It is thus neither possible for the function to check for an out of bounds access nor if array even is an array at all To at least pass along the information that array is an array the following notation should be preferred 1 int getFirst int array 2 return array 0 3 When dynamically allocated arrays must be allocated using the new operator and consequently be deleted using the delete operator Failing to do so and using the normal delete operator would lead to only the first element of the array being deleted and in leaking the
57. gs and pointer to arrays provide a field of spe cial cases for further analysis and would be also a useful addi tion to the plug in e The heuristic to determine ownership can be improved and extended e Pointer tracking using symbolic execution would allow to make large scale refactorings throughout uses of a raw pointer 5 3 Personal Statements This section contains our personal statements on this project 5 3 1 Andr Frohlich The subject of our thesis gave me once more the opportunity to develop an Eclipse plug in and to intensively deal with one aspect of the C programming language In addition this project gave me the chance to deal with Scala and functional programming what 84 5 3 Personal Statements is not part of the regular curriculum at the University of Applied Sciences Rapperswil I could learn a lot about C again Christian Mollekopf had more experience in C and better sense for the pointer issue as I did I was able to greatly benefit from working with him I also benefited from the supervision of Prof Peter Sommerlad who often gave us valuable inputs I used to see smart pointers only as better alterna tive to manual memory management using raw pointer However at the project I learned to appreciate the semantic expressiveness of smart pointers I did enjoy learning Scala Some elements of Scala also helped me to better understand concepts of other programming languages Mirko Stocker s knowl
58. her target statements are identified as occurrences of the same variable Wikipedia Template Method 12 4 2 Quickfix e getNewStatement targetStatement IASTNode isReportedNode Boolean Option IASTNode Returns the refactored replace ment statement for a target statement e handleIncludes r ASTRewrite ast IASTTranslationUnit destination IFolder Unit allows the subclasses to add includes to the ASTRewrite Applying the quickfix then involves e Finding the target statement 1 val targetStatement getTargetStatement astName e Processing all occurrences of the target statement 1 processOccurrences targetStatement get foreach x gt 2 x _2 match 3 case null gt r remove x _1 null 4 case _ gt r replace x _1 x _2 null 5 6 Each statement is either removed if its replacement is null or replaced otherwise The replacement statements are created using getNewStatement e Handling of includes 1 handleIncludes r ast marker getResource getProject getFolder smartor handleIncludes allows subclasses to include header files The subfolder for header includes is hardcoded to smartor e Committing the changes 1 r rewriteAST perform new NullProgressMonitor After this the changes are written back to the file 73 4 Implementation 4 2 3 Includes The plug in supports copying headers to a a project This func tionality is used to include headers shi
59. if src gt IsLoaded 5 common gt Printf couldn t load s n filename 6 delete src 7 return false 8 9 clear 10 parse src 11 delete src 12 return true 13 The code shows the following characteristics e The if clause results in two possible code paths of which both must contain a delete statement in order to get the same result after converting to a smart pointer e The definition of src is separated from its initialization e src is passed to parse requiring either calling src get or converting the argument of parse to a smart pointer e Due to the delete it is ensured that parse didn t take owner ship Example refactored 1 void foo 2 3 std unique_ptr lt const Vehicle gt p new SpecializedCar lt Engine gt 42 4 bar p get O s 44 3 4 Refactoring Cases The pointer can be refactored to a std unique_ptr Because p is passed to bar the raw pointer must be extracted using p get Further the delete had to be removed as the std unique_ptr will delete the resource as it goes out of scope In case a std make_unique would become available the initialization would look the following 1 std unique_ptr lt const Vehicle gt p make_unique lt SpecializedCar lt Engine gt gt 42 ds Limitations and Edge Cases e The plugin could detect disposal functions and pass the pointer to the disposal function using the smart pointers release method
60. ing as dedicated container for strings void print std string amp string 2 std cout lt lt string a By using the std string class it is immediately clear that string represents a string print doesn t have to delete the object and the strings size is available within the object Just like a normal reference can a char pointer also be a string refer ence const string references are typically used to refer to literals 1 char const p literal Wikipedia C Standard Library 21 3 Analysis Such a literal could be wrapped using the not yet standardized string_view which is a non owning reference to a string Although it is not yet possible replace the use of char pointers with a suitable string class in all cases it is still often possible and future enhancements to the standard should resolve the missing parts String objects can be used with the usual smart pointers when al located on the heap Because smart pointer refactorings for strings would be largely an orthogonal effort to the refactorings for other resources and because the use of C Style strings in modern C code is not recommeded anyways strings are not considered further by this analysis 3 2 Available Smart Pointers Various smart pointers are available to express the semantics a raw pointer can have see table 3 1 on page 13 and to help with the resource management This section provides an overview of available smart
61. ing was on February 20th This report has to be handed in by June 14th 12 00 On the same day the exhibition of the bachelor thesis takes place The date for the final demonstration of this thesis is set on June 24th 2013 1 2 Report Contents This report starts with the mandatory abstract and management summary chapters After this introduction the objectives are de scribed in a separate chapter The analysis chapter shows our in vestigation on pointer roles and their possible transformation into smart pointers Implementation details and notes are described in the following chapter This reports ends with a chapter about our conclusion and personal view on this project The appendix con tains an overview over the environment the plug in was developed 1 Introduction in It also contains a brief introduction to developers interested in picking up this project for further work A user manual shows how the plug in can be installed and used The appendix ends with the nomenclature and bibliography 1 3 Target Audience Readers are expected to have the knowledge a student of the Uni versity of Applied Sciences Rapperswil usually has after study for four semesters Developers interested in working with our code must know some basic Scala concepts This report does not contain an introduction to the Scala language For a quick introduction we recommend A Tour of Scala found on the Scala website For a deeper introduc tion
62. inst types thus helps avoiding conditional statements for type checking Management Summary This thesis describes how error prone C naked pointers can be automatically converted into C smart pointers as well as the development of an Eclipse CDT plug in assisting a developer on this task This chapter gives a brief overview of the motivation the goals and the results of this thesis Motivation C supports the use of pointers A pointer is a data type whose value refers directly to another value stored elsewhere in the com puter memory using its addres Every time a pointer is used it has a special role describing its usage However it is not possible to demonstrate the role with a pointer since it is a low level concept This leads to hard to understand code In C better alternatives are smart pointers The use of smart pointers can demonstrate the role of the pointer and manage re sources with these problems and provides a high lever concept A smart pointer is an abstract data type that simulates a pointer while providing automatic memory management and other featured Dif ferent type of smart pointers provides different semantic meanings such as sharing a reference or transfering ownership Wikipedia Pointer computer programming Wikipedia III Goals The goal of this thesis is to analyse the different pointer roles and how they can be used to replace plain pointer by developing an Eclipse plug in for this t
63. is owning This assumption is not guaranteed to hold true in all cases but is a good heuristic to determine that a pointer holds ownership of the resource By employing this heuristic it is possible to only offer sta unique_ptr as suitable refactoring removing non_owning_ptr from the available choices Note that while a delete of a pointer is a clear indication of ownership of the pointer a lack thereof doesn t automatically mean that the pointer doesn t own the resource The ownership may be transferred to a disposal function or to the caller in case of a factory function Further it is possible that the pointer is stored and cleaned up later on See also 3 3 2 on page 30 It is therefore not possible to apply this heuristic reversely 59 3 Analysis Example 2 3 4 5 void foo Car p new Car 42 delete p Because p is deleted within the scope of this function it can be assumed that p holds ownership of the resource Specific Example e sourcefile DOOM 3 neo tools radiant splines cpp 1307 1323 e function idCameraDef load e variable src 1 al oOo N Q 10 11 12 13 bool idCameraDef load const char filename idParser src src new idParser filename LEXFL_NOSTRINGCONCAT LEXFL_NOSTRINGESCAPECHARS LEXFL_ALLOWPATHNAMES if src gt IsLoaded common gt Printf couldn t load s n filename delete src return false clear parse
64. ism After the refactoring Base foo is called instead because Derived foo no longer matches This problem can be solved with the aforementioned wrapper approach as migration path or by adjusting overridden methods in the whole type hierar chy Note that this refactoring must be applied to both the declaration and the definition of the function 41 3 Analysis Return value Return values require the adaption of all callers just like function parameters but as the return value is not part of the function sig nature there is no conflict with overloaded functions Note that this refactoring must be applied to both the declaration and the definition of the function 3 4 4 Default Cases For each starting point there are generally two options one per target smart pointer due to the two chosen smart pointers std unique_ptr and non_owning_ptr as described in 3 4 2 on page 38 The default refactoring cases are therefore the following e Local pointer owning pointer e Local pointer non owning pointer e Function parameter owning pointer e Function parameter non owning pointer e Return value owning pointer e Return value non owning pointer This means per identified raw pointer two refactorings are poten tially applicable Because automatically determining ownership of the pointer was deemed to complex in most cases within the scope of this project see 3 3 2 on page 30 it is up to the developer to make th
65. ithout using smart pointers to convey the original intention all that is left to help the reader are comments in the code and 13 3 Analysis coding conventions which are both highly error prone as they are up to interpretation and not checkable by the compiler A raw pointer declaration can have any role of the following list or a combination thereof e reference e reassignable reference e handle to dynamically allocated memory e optional e error code e array e string Note how the pointer declaration above doesn t reveal anything about the developers intentions or the roles the pointer could have and thus all semantics are hidden in the declarations context com ments how the pointer is used common patterns The following sections explain each of the mentioned roles where they typically appear on how they could be represented in a way that conveys the semantics using smart pointers and other intention revealing language constructs such as references For a description of the used smart pointers in this section see on page 22 Reference 1 void foo int ref 2 int i ref 3 14 3 1 Pointer Roles A pointer can be the C implementation of the C reference A reference is by definition non owning but can be const or non const Further can the reference refer to stack or heap allocated data struc tures A reference must be initialized and may not be reassigned the referenced value can be re
66. lenmld smartPointerArgumentToRawPointer argument 6 case SinglePointerParameter parameter gt placeMarkers ProblemId rawPointerParameter parameter 7 case FunctionDeclarator ContainsPointerNonRecursive parameter gt placeMarkers Problemld rawPointerReturn parameter a 8 case _ gt node getChildren foreach traverseTree 9 10 traverseTree provides a method that recursively traverses each node in the AST and gets called by processAst Inside this method each node is matched using extractor objects So instead of relying on the double dispatch mechanism of the visitor to pro cess particular node types Scalas matching capabilities are used to match specific patterns within the AST This helps to keep the core logic of the Checker together in one place with all the logic for the actual pattern matching externalized into custom extractor objects Each detected problem is reported using placeMarkers 1 private def placeMarkers problem Problemld ProblemId node IASTNode Unit 2 val definition ProblemDefinitionFactory getProblemDefinition problem 66 4 1 Checker 3 reportProblem definition getErrorld node definition getProblemName The reported problems are finally displayed to the user as marker in the editor see 4 1 on page 63 which allows the user to get a problem description and to trigger associated quickfixes 4 1 2 Pattern matching The Checker makes extensive
67. logic between the often similar quickfixes a type hier archy was introduced 70 4 2 Quickfix QuickFix SmartPointerDefinition SmartPointerQuickFix SmartPointerFactory LocalToNonOwningPtr LocalToUniquePtr FunctionQuickFix gt ParameterToNonOwningPtr ParameterToUniquePtr ReturnToNonOwningPtr ReturnToUniquePtr QuickFix is the base class for all quickfixes It provides the frame work to identify the marked statement in the sourcecode traverse all occurrences of a variable and to finally commit the changes to the sourcecode SmartPointerQuickFix is the base class for all quickfixes that refactor the use of raw pointers to smart pointers It contains the code to replace initialization and assignment statements containing raw pointers with equivalents for smart pointers FunctionQuickFix is the base class for all quickfixes that modify the function itself and not only its body i e parameters and return value It contains the necessary logic to traverse all uses of the function to be able to adjust the callers accordingly SmartPointerDefinition The abstract class SmartPointerDefinition encapsulates the partic ularities of the individual smart pointers In particular e The namespace the smart pointer is in 71 4 Implementation e The name of the pointer e The header to include e
68. me that MemoryManagementUnit is a facility that manages the lifetime of all objects registered with it MemoryManagementUnit register takes therefore ownership of pointers passed to it In line 2 the constructed object passes ownership to the MemoryManagementUnit by calling register Although o is initial ized directly from the new expression in line 6 o never receives ownership of the object Similarly it is possible that an object passes its ownership some where during a function call 1 struct Object 2 void doSomething MemoryManagementUnit register this Object o new Object o gt doSomething While o initially receives ownership in this example on line 5 it looses it rather unexpectedly in line 6 during the call to doSomething This ownership transfer would go unnoticed when only checking for external assignments It would be possible to check for this different memory management model by ensuring that the this pointer is not stored anywhere from within the object As a real world example such a memory management model is for instance implemented in the Qt Framework with QObject With QObject each object can register itself with the parent object pass ing it s ownership to the parent The parent object is then respon sible for managing the lifetime of its childrer As this memory management model doesn t work together with the one used for smart pointers this issue is ignored for
69. n A function declarator containing a raw pointer as return value 1 int get The reported problems correspond to either a starting point de fined in Section or a combination of a start ing point and a heuristic This approach allows quickfixes to be registered on specific combinations of starting points and heuris tics For instance is the refactoring for a non_owning_ptr on a lo cal pointer not registered on ch hsr ifs cdt smartor plugin error LocalPointerWithLocalDelete because we know that this refactoring is not applicable in this case because the pointer has ownership of the resource 4 1 1 Control Flow The primary entry point to process the AST is 1 def processAst ast IASTTranslationUnit Unit This method get s called whenever the AST must be reevaluated Although the framework would provide the visitor org eclipse cdt core dom ast ASTVisitor to traverse the AST this facility was not used to make use of Scala s pattern matching instead 65 4 Implementation 1 private def traverseTree node IASTNode Unit 2 node match 3 case DeclarationStatement ContainsPointer HasLocalDelete declarationStatment gt placeMarkers Problemld localPointerWithLocalDelete node 4 case DeclarationStatement ContainsPointer parameter gt placeMarkers Problemld localRawPointer parameter case FunctionCallStatement SmartPointerArgumentToRawPointerParameter argument gt placeMarkers Prob
70. nsions for building Eclipse plugins e GCC 4 8 is used to compile C files and support the new C 11 standard e TX is the document markup language we used to write this thesis 93 B Environment B 2 Eclipse Plug ins To develop an Eclipse plug in using Scala several plug ins are re quired This section shows what plug ins we used and what they are good for B 2 1 Installation Where not otherwise specified we used the Eclipse Juno update site To install a plug in simply go to Help Install New Software 94 Available Software Check the items that you wish to install Work with Juno http download eclipse org releases juno Find more software by working with the Available Add ftware Sites preferences plug in Name U 001 Collaboration B lt p EGit Plug in Import Support G Mylyn Context Connector Plug in Development will General Purpose Tools 5 Eclipse Plug in Development Environment SelectAll Deselect All 1 item selected Version 2 2 0 201212191 3 8 3 v20130107 3 8 2 v20130116 Details Eclipse plug in development environment aw Show only the latest versions of available software C Hide items that are already installed Group items by category What is already installed C Show only software applicable to target environment M Contact all update sites during install to find required software Finish
71. o do is find declarations and offer all available refactoring options While the new task is a lot simpler and far more straightforward it still requires a lot of time to implement which we didn t have at this point in time Nevertheless we tried our best to still achieve something useful within that timeframe and hope the result goes now more in the expected direction However there were also very positive aspects in the project I enjoyed a lot to work with Scala which was a breath of fresh air in the Java landscape I think Scala has a lot of nice concepts and although I m far from really understanding the full capabilities of the language I still got a nice insight and would definitely consider to write my next project where I m forced to interact with Java using Scala I also ended up thinking a lot about programming languages in terms of semantics of expressions where even seemingly trivial things like the identifier not being the same as the underlying variable and why it can get messy if the underlying value can change really started to become clear to me I got to appreaceate the conveyed semantics by various language constructs and smart pointers more optional being one of constructs I always made a circle around so far and where I now can think of loads of places where I wished it was 87 5 Conclusion used default constructed values really can t be the solution to that problem Overall the project en
72. o int x e A pointer return value int foo The starting points have been chosen because they seemed like nat ural starting points for a conversion i e where one would want to apply a quickfix and due to expected feasibility Further potential starting points that have not been analysed are e Global variables e Class members Local pointer Local pointers are the simplest case due to their limited visibility Therefore only the scope the local variable needs to be considered Function parameter Function parameters are different from local variables because they are visible outside of the scope of the function Therefore also the caller code needs to be considered Note that because the func tion parameter is visible inside the scope of the function the same refactorings apply as for local pointers If a function is modified to take a smart pointer instead of a raw pointer as argument the signature changes These are the implica tions for callers e There can be a type mismatch when a caller tries to pass in a raw pointer 39 3 Analysis void foo non_owning_ptr lt Car gt car Bow No al 6 Car car 7 foo car The call to oo fails because the constructor of non_owning_ptr is explicit e The compiler could choose a different overload which may go unnoticed leading to unexpected behaviour void foo Vehicle before refactoring void foo Car car oo oo vv A OU
73. of a resource employing a reference count and deletes the resource once it is no longer ref erenced It can therefore be freely copied while ensuring that no memory leak occurs std shared_ptr should be created using std make_shared Support for dynamically allocated arrays has been discussed but not yet proposed for the standard 3 2 5 std weak_ptr std weak_ptr holds a non owning reference to an object managed by a std shared_ptr It doesn t increase the reference count and thus doesn t prevent the resource from being deleted but tracks the deletion of the object so it doesn t result in a dangling pointer To access the referenced object the std weak_ptr must be converted to a std shared_ptr first to assume temporary ownership 3Lavavej N3588 make_unique 4Sutter Trip Report ISO C Spring 2013 Meeting 5Hinnant Why isn t there a std shared_ptr lt T gt specialisation 24 3 2 Available Smart Pointers 3 2 6 std auto ptr deprecated std auto_ptr takes sole ownership of a resource and deletes it upon destruction Copying an std auto_ptr transfers the ownership to the target resulting in unusual copy semantics Due to the unusual copy semantics and the lack of move semantics std auto_ptr may not be placed in standard containers As of C 11 std auto_ptr is deprecated and replaced by std unique_ptx 3 2 7 non_owning ptr non_owning_ptr holds a non owning reference to an obj
74. on_owning_ptr may be better suited 1 non_owning_ptr lt int gt ref getRef 2 for int i 0 i lt 3 i 3 if condition i 4 ref getRef i s 6 ref getNewValue non_owning_ptr behaves exactly like a raw pointer but clearly shows the intent that ref is a non owning reference Handle to dynamically allocated memory A raw pointer may represent a handle with ownership to dynami cally allocated memory Having ownership means that the holder of the handle is responsible to release the allocated memory before disposing of the handle Typical examples are factory and disposal functions int create 1 2 return new int 3 3 4 void dispose int p 5 delete p 6 The raw pointers returned from create and passed to dispose own the resource but give no indication that they do To better communicate the semantics of the pointer std unique_ptr and std shared_ptr are available where std unique_ptr 16 3 1 Pointer Roles holds sole ownership of the resource and std shared_ptr shared ownership for further information about the smart pointers see 3 2 on page 22 1 std unique_ptr lt int gt create 4 2 return std unique_ptr lt int gt new int 3 By returning a std unique_ptr it is clear that the caller gets the ownership of the resource and that the resource is not meant to be shared create can return a std unique_ptr using move semantics 1 std shared_
75. owning_ptr came into the picture and we suddenly started to discuss things like boost optional which I would never have introduced to the project due to my understanding However I ve seen the semantics as bonus points while the primary target still was to remove the manual resource management Of course I should have realized that this is not what was expected but at this point I was already deep down the rabbit hole called tracking pointer ownership The ownership of a pointer is indeed an important 86 5 3 Personal Statements feature to be able to automatically refactor a memory management system but not so much to to attach semantics to a pointer where we either need no tracking at all or only have to track within a very limited scope In the end we wanted to solve a problem which was much to difficult within the scope of this project and didn t realize that this wasn t the problem we were expected to solve We also realized too late that the problem we wanted to solve was much too difficult After realizing we unfortunately only had two weeks left within which we basically had to rewrite the whole analysis as the approach we started with didn t really fit anymore For instance it didn t make sense anymore to try to identify specific patterns in the code which can be refactored which we did because we wanted identify specific constellations in which we can determine the ownership if all we really had t
76. pped with the plug in such as exempt_ptr h This works especially well because many smart pointers such as the boost implementation are header only im plementations which makes it easier to include the smart pointer implementations Includes are shipped in the headerFile ptor subdirectory of the plug in and are copied to the smartor subdirectory of the target project The handling of includes is implemented in SmartPointerQuickFix handleIncludes which adds an include statement to the source file if not already present and copies the header if SmartPointerDefinition copyHeader is true To ensure that the header is found the include path of the target project needs to be adjusted which is done automatically by the GnuCppIncludePathAdder GnuCppIncludePathAdder adds a new include path relative to the target workspace to the project if not already present 4 3 Checker Quickfix association The problems which can be reported by the checker are registered in plugin xml 1 lt extension 2 point org eclipse cdt codan core checkers gt 3 lt checker 4 class ch hsr ifs cdt smartor checker Checker 5 id ch hsr ifs cdt smartor plugin Checker 6 name Smartor Warning Checker gt 7 lt problem 74 4 4 Tests 8 category org eclipse cdt codan core categories CodeStyle 9 defaultEnabled true 10 defaultSeverity Warning 11 description Smartor Warning 12 id ch hsr ifs cdt smartor plugin error Loc
77. ptr lt int gt create 2 return std make_shared lt int gt 3 3 By returning a std shared_ptr it is clear that the caller gets the ownership of the resource and that the resource is meant to be shared Both variants ensure by returning a resource managing smart pointer that the resource is not leaked std unique_ptr and std shared_ptr typically occur as return val ues function parameters or local variables Note that these smart pointers not only communicate the intent of the developer but also take over the responsibility for the resource management by ensuring that the resource is deleted when no longer required Optional Raw pointers can be used for optional values that are not guaranteed to be initialized The convention is typically that if the pointer is NULL the value is not available 17 3 Analysis 1 void foo int value 4 2 if value 3 addToList value 4 5 Because the value can be NULL it can be used as optional value Note that this implementation passes value by reference Optionals typically occur as return values or function parameters boost optional provides an explicit way to mark a value as op tional 1 void foo boost optional lt int gt value 2 if value 3 int i value 4 5 boost optional indicates that value is indeed optional Note that this implementation passes value by value Since smart pointers can be empty optional can be impl
78. rest of the array Arrays are a special case of a raw pointer imposing the same prob lems as pointers to other resources but with special allocation and deallocation operators The solutions are thus largely orthogonal std unique_ptr already supports array operators new delete and std shared_ptr may support them in future versions see also Section 3 2 on page 22 Additionally boost shared_array exists As plain arrays are a very low level concept essentially pointer arithmetics they should not normally be used Instead the C 20 3 1 Pointer Roles Standard Library provides containers such as std vector and std list which are in most cases preferred The containers can be used in conjunction with one of the usual smart pointers when allo cated on the heap Because smart pointer refactorings for arrays would be largely an orthogonal effort to the refactorings for other resources and because the use of plain arrays in most modern C code is not recommeded anyways arrays are not considered further by this analysis String Strings are a special case of vectors and as such also degrade to raw pointers when passed to a raw pointer variable void print char string 2 std cout lt lt string a string doesn t convey any information if it is a pointer to a single char an array of char s or indeed an array of chars representing a string The Standard C Library thus provides std str
79. roach the advantage that the changes from a refactoring are usually applied to the code the developer is currently working on making it easier for the developer to review the changes and also giving finer grained control over the refactored parts of the source code The analysis is based on the smart pointers available in Standard C Library If other smart pointers i e boost should be used a smart pointer with the same semantics has to be chosen see Ta ble 3 1 on page 23 For cases where no standard smart pointer exists boost is the preferred alternative The following guidelines are generally applicable to all refactor ings e Preserve the lifetime of the object Using a smart pointer should not change the lifetime of the object 1 void foo 2 1 3 MyClass p new MyClass 4 bar p 35 3 Analysis 36 delete p MyClass p2 new MyClass delete p2 oo N Q A By turning p into a local smart pointer both objects would live until the end of foo resulting in a change of lifetime for p As this could lead to problems and p was deleted on purpose before allocating p2 such changes of lifetime must be avoided for instance by calling p release Don t change semantics of the pointer i e constness should be preserved 1 MyClass const p new MyClass 2 becomes 3 std unique_ptr lt const MyClass gt p new MyClass Don t change the scope of the pointer i e don t move
80. roject can be continued It also includes our personal state ments 5 1 Accomplishments During this bachelor thesis we examined how a plug in can assists a developer at finding raw pointers and convert them into smart pointers The following achievements are notable e The thesis contains an analysis of pointer roles as well as their possible conversions into smart pointers e Although the ownership tracking approach was not successful it analyses where the problems lie which could be useful for future work on the topic e We created an Eclipse CDT plug in that finds raw pointer is sues and marks them in the editor The developer may choose to manually resolve the issue or invoke a quick fix we provided for various cases The quick fix automatically converts the pointer into a suitable smart pointer e The plug in has support for smart pointers introduced with C 11 as well as a newer smart pointer proposal that is going to be implemented in a future C version 83 5 Conclusion e We verified that Scala is benefical in many areas of our project The pattern matching mechanism resulted in cleaner and more readable source code It is a neat way to match against types and thus helps avoiding conditional statements for type check ing 5 2 Future Work There are multiple options to continue this project e The handling of all special cases can be finished based on the already implemented test cases e Pointer to strin
81. rtor p2repository contains the plug in p2repository e documentation contains the KTEXdocumentation The root folder as well the subfolders are Maven projects containing its pom xml file Note that the documentation is also built using Maven C 5 1 Manifest and plugin xml Dependencies are set in the MANIFEST MF and plugin xml files Eclipse provides an Plug in Manifest editor helping with editing these files C 5 2 Target file The target is used to store the plug ins required to run the plug in When it is activated the plug ins listed in it doesn t need to be installed in the Eclipse instance that is used to develop the plug in Target files are activated workspace wide and not per project C 5 3 Markers Markers are part of the Eclipse CDT Codan project As part of the static code analysis framework they provide an interface to mark passages of the source in an editor Multiple markers per line are possible as they are stacked The entry point for markers is the Checker class located in the ch hsr ifs cdt smartor checker package It extends the AbstractIndexAstChecker class and overrides the processAst Method Scalas match Statement is used to distinguish the differnt cases 107 C Developer Guide Possible problem cases are defined in the Problemdefinitions scala file in the ch hsr ifs cdt smartor package Testing is done with the SmartorCheckerTest class It is located in the ch hsr ifs cdt smartor test pack
82. s 61 3 Analysis would be available to represent certain roles these two allow to refactor the code with fewer other changes required and support refactoring only part of the code while the rest still uses raw pointers This is important to be able to gradually convert the use of raw pointers to smart pointers while being able to review and test each step Although it would be possible to automatically determine the suit able smart pointer to use based on the ownership of the pointer it is shown that the analysis of the ownership of a raw pointer can be very complex because the semantics can change for the same iden tifier in each code path Hence a full analysis would be too difficult to implement based on the information provided by the abstract syntax tree within the scope of this project Due to this complexity fully automated refactorings adjusting all uses of a pointer automatically were not implemented Instead the chose approach provides possible refactorings for the developer to choose and only taking small steps in those refactorings The de veloper who understands the code can then make the necessary de cisions and review the applied changes This analysis also highlights one of the great benefits of smart point ers the revealed semantics While it is usually possible for a devel oper to guess the correct semantics of a pointer after having looked at enough context it can be a lot of work to correctly analyze it
83. s template unique_ptr 20 7 1 provides a better solution end note 2012 Wikipedia Abstract Syntax Tree Online accessed 25 05 2013 2013 URL Wikipedia C Standard Library Online accessed 25 05 2013 2013 URL Wikipedia Factory Method Online accessed 25 05 2013 2013 Wikipedia Pointer computer programming Online accessed 01 06 2013 2013 UR php title Pointer _ computer _ programming amp oldid 554897073 Smart pointer Online accessed 01 06 2013 2013 URL en wikipedia org w index php title Smart_pointerg oldid 556415178 Wikipedia Template Method Online accessed 25 05 2013 2013 URL http en wikipedia org wiki Template_method_ attern i Yasskin Jeffrey N3609 string_view a non owning reference to a string revision 3 Online accessed 28 04 2013 2013 URL http www open std org jtc1 sc22 wg21 docs papers 2013 n3609 html 118
84. se of a later initialization or reassignment the pointer must be created using make_nonowning 1 non_owning_ptr lt const Vehicle gt p 2 p make_nonowning getReference Limitations and Edge Cases e The initialization for the pointer may also occur at a later stage no direct initialization In this case both the definition of the pointer and the initialization must be adjusted accordingly Note that a reassignment can be handled in the same way e If a function parameter to which the pointer is passed already uses a non_owning_ptr the pointer can be passed directly in stead of wrapping it with make_nonowning void bar non_owning_ptr lt Vehicle gt 1 2 3 Vehicle p new Car 42 4 bar make_nonowning p 5 becomes 6 non_owning_ptr lt Vehicle gt p make_nonowning lt Car gt 42 7 bar p 49 3 Analysis e If the pointer is initialized from a function return value and the return value already uses a non_owning_ptr the smart pointer can be copy constructed instead of using get non_owning_ptr lt Vehicle gt getRef becomes 1 2 3 Vehicle p getRef O get 4 5 non_owning_ptr lt Vehicle gt p getRef e If the pointer is returned from a function with a raw pointer return value the raw pointer must be extracted using get 1 non_owning_ptr lt Vehicle gt getRef 2 Vehicle foo 3 1 4 std non_owning_ptr lt Vehicle gt p getRef 5 return p get 6
85. sing this update site https raw github com jeeeyul eclipse themes master net jeeeyul eclipse After the installation it can be activated in the Eclipse preferences under General Appearance Once it is active it can be cus tomized in General Appearance Chrome Theme B 2 6 IFS CDT Testing This plug in helps to test Eclipse CDT plug ins The update site is found on http dev ifs hsr ch updatesites cdttesting juno B 2 7 Issues Run Configurations To avoid the Setup Diagnostics dialog while testing the plugin it is recommended that the Scala IDE isn t launched with the plug in This can be achieved by editing the Run Configurations In the Plug ins tab Launch with should be changed to plug ins selected below only Disable all unnecessary plug ins like those of the Scala IDE However a Scala library is however needed and the plug in providing it must remain enabled As an alternative it is also possible to select org eclipse platform ide instead of org eclipse sdk ide in the Run Configuration in the Main tab under Run a product Alternatively a target file can be used After the activation its configuration is workspace wide active 96 Eclipse CDT C 11 support B 2 Eclipse Plug ins Support for C 11 is not provided out of the box by the Eclipse CDT version we used This section describes what may be neces sary ene
86. src delete src return true The delete on src gives the indication that src is owning and could therefore be refactored to a std unique_ptr 60 3 5 Conclusion Limitations and Edge Cases e If the code would have multiple codepaths for instance due to an if statement it would have to be ensured that each codepath contains a delete As a simplification the plugin assumes that all codepaths contain a delete if a delete statement was found in the current scope e The plugin could detect disposal functions and determine ownership accordingly e If the pointer variable is reassigned or if the pointer passed ownership somwhere else between initialization of the pointer variable and its deletion this heuristic could deliver wrong results The following artificial example illustrates a case where the heuristic would not apply void foo A ME i 3 Car p getReference 4 p gt doSomething 5 p get 6 delete p 7 Although p represents a reference at first it receives owner ship in line 5 due to the assignment assuming get returns an owning pointer In this case a refactoring to a std unique_ptr would give the false impression that p holds own ership from the beginning 3 5 Conclusion The analysis shows when ignoring the special cases of arrays and strings all roles of a raw pointer can take can be expressed using std unique_ptr and non_owning_ptr While other language construct
87. syntactically less intrusive and has the addi tional advantage that it may be reassigned which again removes a special case Values on the stack are not considered because the same ownership semantics can be achieved using std unique_ptr sole ownership 29 3 Analysis destruction as the identifier goes out of scope Further may the move from heap to stack be undesirable due to platform limitations such as the stack size limit Le if the object was managed on the heap before nothing has changed in that regard that would justify why the object should be managed on the stack after the refactoring Like C references is a refactoring to a value also syntactically a rather intrusive change 3 3 2 An approach for automatic determination of a suitable smart pointer When only considering std unqiue_ptr and non_owning_ptr for a refactoring for the reasons lined out in the previous section a primary point of distinction is the ownership of the pointer It is therefore possible to automatically select the appropriate smart pointer by determining the ownership of a raw pointer This section analyses how the ownership of a raw pointer can be de termined and highlights the difficulties inherent to the approach Determining ownership of a raw pointer To automatically select an appropriate smart pointer based on the ownership of the raw pointer ways to automatically determine own ership are required There are two places where
88. t META INF MANIFEST MF build properties e Feature xml product files target files e category xml 103 B Environment B 6 2 Documentation To build this thesis we used a KTEXplugin for Maven called LaTeX Mojo This plug in also helps to generate a simple EITFXproject skeleton 1 mvn archetype create 2 DarchetypeGroupId org codehaus mojo 3 DarchetypeArtifactId latex maven archetype 4 DarchetypeVersion 1 1 5 DgroupId ch hsr ifs 6 DartifactId thesis The document can be build using the latex latex Maven goal 1 cd thesis 2 mvn latex latex There is additional documentation about this plug in the project website http mojo codehaus org latex maven plugin B 6 3 Jenkins Jenkins is an open source continous integration tool written in Java We setup two projects one for the plug in and antoher one for the documentation Since both projects are build using Maven the setup is straightforward In order that Jenkins is able to fetch the latest sources we use the Git Jenkins plug in 3Eclipse Jenkins 104 C Developer Guide This chapter guides through the process of setting up a development environment to extend the plug in described in this thesis C 1 Java Scala and other tools For developing the following tools are required e Java Scala e Git e Maven For more information about the tools refer to the environment sec tion of this appendix C 2 Installing
89. t summary and abstract will be written to document the project Further deliverables will be pro vided according to the HSR bachelor thesis requirements Example The following example shows a function that takes a raw pointer as parameter x modifies x s pointee using a member function call and returns a heap allocated resource of type T2 T2 T1 const x 1 2 4 3 if x 4 x gt set 1 5 return new T2 6 2 Objectives x is anon owning reference to a object since f contains no delete and x s pointee is modified so it should be converted to a non_owning_ptr to make the semantics clear By using non_owning_ptr we make ex plicitly clear that f doesn t take ownership and that it may modify x s pointee Since x may be null we also can t convert x to a ref erence The return value could be either a std unique_ptr or a std shared_ptr Which one is suitable is not visible without more context but for this example we ll assume std shared_ptr is what we want The converted result would therefore look like this 1 std shared_ptr lt T2 gt f non_owning_ptr lt T1 gt const x 2 4 3 if x 4 x gt set 1 5 return make_shared lt T2 gt 6 In the result the semantics and responsibilities of f and the caller are much clearer It s clear that x may be modified by f and that x is still valid after the call to f It is also clear that the caller of f owns the returned object and the potential m
90. ter A smart pointer for single ownership 115 F Bibliography Boost boost shared_ptr class template Online accessed 28 04 2013 2013 URL Brown Walter E N3514 A Proposal for the World s Dumbest Smart Pointer Online accessed 28 04 2013 2012 URL par Eclipsepedia CDT designs StaticAnalysis Online accessed 25 05 2013 2013 URL Hinnant Howard Why isn t there a std shared_ptr lt T gt special isation Online accessed 28 04 2013 2013 URL Lavavej Stephan T N3588 make_unique Online accessed 28 04 2013 2013 URL http www open std org jtc1 sc22 wg21 docs papers 2013 n3588 txt Odersky Martin Lex Spoon and Bill Venners Programming in Scala Second Edition Updated for Scala 2 8 Walnut Creek Calif artima 2010 ISBN 978 0981531649 qt project org QObject Trees amp Ownership Online accessed 25 05 2013 2013 URL Qt Project Online accessed 25 05 2013 2013 URL qt project org scala lang org A Tour of Scala Online accessed 06 06 2013 2013 URL http www scala lang org node 104 Software IDE DOOM3 Sourcecode Online accessed 25 03 2013 2013 URL https github com id Software DOOM 3 117 F Bibliography Sutter Herb Trip Report ISO C Spring 2013 Meeting Online accessed 28 04 2013 2013 URL Toit Stefanus Du N3337 Working Draft Standard for Programming Language C The class template auto_ptr is deprecated Note The clas
91. ter can be moved using std move instead of wrapping it with a constructor call void bar std unique_ptr lt Vehicle gt 1 2 3 Vehicle p new Car 42 4 bar std unique_ptr p 5 becomes 6 std unique_ptr lt Vehicle gt p new Car 42 ie 7 bar std move p If the pointer is initialized from a function return value and the return value already uses a std unique_ptr the smart pointer can be copy constructed instead of using release std unique_ptr lt Vehicle gt create becomes std unique_ptr lt Vehicle gt p create 1 2 3 Vehicle p create release 4 If the pointer is passed to a function which takes ownership of the pointer but doesn t have a smart pointer parameter the pointer must be released using release instead of get 3 4 Refactoring Cases e If the pointer is returned from a function with a raw pointer return value the raw pointer must be extracted using release O 1 Vehicle create as Ml 3 std unique_ptr lt Vehicle gt p new Car 42 4 return p release 3 4 6 Local pointer non owning A local pointer is non owning if it is initalized by a reference It can therefore be refactored to a non_owning_ptr Example void bar Vehicle const Vehicle getReference void foo Vehicle const p getReference bar p oO s Q oa A w N e The pointer has a const modifier which must be preserved during conversion
92. the code which are then reported to the Codan framework 63 4 Implementation The Codan framework provides an AST which is then evaluated by the checker to identify the required parts The checker is implemented as single class that derives from org eclipse cdt codan core cxx model AbstractIndexAstChecker an extension point provided by Codan for code checking plug ins org eclipse cdt codan core cxx model AbstractindexAstChecker Checker Figure 4 2 The checker type hierarchy The following patterns are evaluated in the given order with pat terns listed first taking precedence and the associated problem being reported e ch hsr ifs cdt smartor plugin error LocalPointerWithLocalDelete A declaration statement containing a raw pointer with a delete in the local scope 1 int i new int 3 2 delete i e ch hsr ifs cdt smartor plugin error LocalRawPointer A declaration statement containing a raw pointer 1 int i new int 3 e ch hsr ifs cdt smartor plugin error SmartPointerArgumentToRawPointer 64 4 1 Checker A function call statement with a smart pointer argument passed to a raw pointer parameter 1 void foo int 2 non_owning_ptr lt int gt i make_nonowning lt int gt 3 3 foo i e ch hsr ifs cdt smartor plugin error RawPointerParameter A parameter declaration containing a raw pointer 1 void foo int i e ch hsr ifs cdt smartor plugin error RawPointerRetur
93. the Eclipse IDE Eclipse can be downloaded from Any package can be used as the needed plug ins can be installed later A good choice is the Eclipse IDE for Java Developers oder the Eclipse for RCP and RAP Developers package It is also possible to use the Scala IDE Elipse distrubtion that can be found on 105 C Developer Guide C 3 Plug ins There is a set of plug ins we recommend e C C Development Tools e Eclipse for RCP and RAP Developers e Tycho Project Configuratiors e Scala IDE for Eclipse e IFS CDT Testing Feature e Jeeyul s Themes Jeeyul s Themes allows to modify the appearance of Eclipse It is helpful to give multiple Eclipse instances different colors in order to easily distinguish them C 4 Importing the project The source is avaiable as a Git repository A virtual server is avaible that provides a central repository Since the life time of the server is limited this repository may no longer available A copy of the repository is also provided on the compact disc of this thesis The repository contains the source of the plug in as well as of the documentation C 5 Source overview The source is distributed over multiple folders e ch hsr ifs cdt smartor contains the plug in source project e ch hsr ifs cdt smartor feature contains the plug in featuer project 106 C 5 Source overview e ch hsr ifs cdt smartor test contains the plug in test project e ch hsr ifs cdt sma
94. thus added for the sake of completeness Smart Pointer Boost Smart Pointer Description std unique_ptr boost scoped_ptr takes sole ownership manages life time std shared_ptr boost shared_ptr shared ownership manages lifetime std weak_ptr boost weak_ptr non owning reference to object man aged by shared_ptr std auto_ptr predecessor of std unique_ptr non_owning_ptr a non owning reference optional boost optional optional value not a smart pointer boost scoped_array scoped pointer for arrays boost shared_array shared pointer for arrays boost intrusive ptr shared pointer with externalized ref erence count Table 3 1 Available Smart Pointers 23 3 Analysis 3 2 3 std unique_ptr std unique_ptr takes sole ownership of a resource and deletes it upon destruction It is therefore non copyable but supports move semantics and can thus be used in containers supporting move se mantics e g std vector Currently a new expression is still required to create a resource that is wrapped by a std unique_ptr but a make_unique similar to make_shared has already been pro posed and will likely be included in a future version of the C standard For dynamically allocated arrays std unique_ptr sup ports std unique_ptr lt T gt instead of std unique_ptr lt T gt 3 2 4 std shared_ptr std shared_ptr takes shared ownership
95. ts can be nested inside the expression 4 2 Quickfix The quickfixes apply the actual refactoring to the code when acti vated Because the quickfix class is used to associate a quickfix with a reported problem see 4 3 on page 74 each quickfix needs to be in it s own class Each marker has an associated problem id for which quickfixes can be registered This allows to decouple the detection of a potential problem and a proposed quickfix The following quickfixes were implemented in the ch hsr ifs cdt smartor quickfix quickfixes package e LocalToNonOwningPtr Local raw pointer to non_owning_ptr refactoring e LocalToSharedPtr Local raw pointer to std shared_ptr refac toring not used LocalToUniquePtr Local raw pointer to std unique_ptr refac toring 69 4 Implementation e ParameterToNonOwningPtr Raw pointer parameter to non_owning_ptr refactoring e ParameterToUniquePtr Raw pointer parameter to std unique_ptr refactoring e ReturnToNonOwningPtr Raw pointer return value to non_owning_ptr refactoring e ReturnToUniquePtr Raw pointer return value to std unique_ptr refactoring e ExtractRawPointer Refactoring to extract raw pointer from a smart pointer argument using get if the argument is passed to a raw pointer parameter e ExtractRawPointerAll Mass refactoring for ExtractRawPointer that is automatically applied to all uses of an identifier 4 2 1 Architecture To share the
96. ustrating to see that we were run ning again in many setup and buildsystem problems Although most problems could be solved in the end and often proved to be a real issue in a configuration file or the other the errors often appeared without any specific action taken and seldomly with a useful error description This cost a lot of time during the project that would have been better spent otherwise It was however a familiar expe rience working with the eclipse frameworks with its overly loose coupling As we established in our second last meeting that we apparently didn t have the same understanding of our task as our advisors was obviously also not necessarily what we had hoped for According to our task description our target was to analyse how raw pointers can be refactored into smart pointers and provide suitable refactorings There are however different approaches to that Before the project my personal understanding of what a smart pointer is for was the memory management and never really the revealing of semantics I though of it really just as a way for the compiler to enforce that there is no memory leak Coming from that line of thought there are only two major smart pointers std unique_ptr and std shared_ptr and naturally I also assumed that the primary motivation for using smart pointers was to get rid of the error prone manual memory management Of course I started to see the value of the semantics especially aS non_
97. various containers such as Option and Array 1 array foreach val gt 2 doSomething val 3 4 6 7 Concise notation Scala supports a very concise notation by allowing to skip many unnecessary symbols such as semicolons braces in function calls and variable identifiers To give you an idea 79 4 Implementation e Semicolons can be omitted when at the end of a line e Overridden functions don t require the full function declara tion 1 A function with a String as return value 2 override def getLabel Quickfix Label 3 A function with a Option IASTNode as return value 4 override def getTargetStatement node IASTNode Some node Note that in the second example the argument only needs to be specified because node is used in the assigned expression e Braces can be ommited when calling getters 1 marker getResource getProject getFolder smartor This greatly helps to reduce the boilerplate code that needs to be written and to remove the visual clutter 4 6 8 Java Conversions Although it is possible to maintain a mixed maven project using the Scala maven plugin that means using Scala and Java source files in one project we decided to go with a pure Scala way for simplicity reasons For that reason we had to convert some source files we work with into Scala The conversion was not very difficult and more or less a one to one translation from Java source code statements into Scala To deal
98. wCamera idCameraPosition positionType type 2 clear 3 if type idCameraPosition SPLINE 4 4 cameraPosition new idSplinePosition O 5 else if type idCameraPosition INTERPOLATED 4 6 cameraPosition new idInterpolatedPosition 7 else 8 cameraPosition new idFixedPosition O 9 10 return cameraPosition 1 gt The code shows the following characteristics e The if clauses result in 3 different codepaths of which all re turn an owning pointer 56 3 4 Refactoring Cases Example Refactored 1 std unique_ptr lt Vehicle gt createVehicle 2 A 3 return std unique_ptr lt Vehicle gt new Car 4 6 void main 7 i 8 Vehicle vehicle createVehicle release 9 The return value can be refactored to a std unique_ptr Each return statement must be adjusted to use std unique_ptr Each caller must be adjusted to extract the raw pointer using release Limitations and Edge Cases e If a caller already uses a std unique_ptr it can be initialized directly instead 1 std unique_ptr lt Vehicle gt vehicle createVehicle 3 4 10 Return value non owning pointer A function may return a pointer as non owning reference Example 1 Vehicle getVehicle 2 3 static Car car 4 return amp car 5 57 3 Analysis 6 7 void main s 1 9 Vehicle vehicle getVehicle 10 Note that this is not a factory function but resembles som

Download Pdf Manuals

image

Related Search

Related Contents

  USER GUIDE: SUBMITTING ONLINE  Case Logic INS-3W  33 trier des textes 1  Sandberg Monitor Cable DVI-DVI 2 m  Network Wind User Manual  経済産業省-低煙源工場拡散モデル (Ministry of  取扱説明書 注 意  TC-32LX80LA TC-32LX80LU  User`s Manual Gas Ranges  

Copyright © All rights reserved.
Failed to retrieve file