Differences

This shows you the differences between two versions of the page.

Link to this comparison view

dss:laboratoare:03 [2019/06/13 14:17]
razvan.nitu1305
dss:laboratoare:03 [2019/06/21 13:10] (current)
razvan.nitu1305
Line 1: Line 1:
-===== Lab03: Memory Safety =====+===== Lab 03: Memory Safety =====
  
 During this lab you will learn about the memory safety mechanisms that are available in D. During this lab you will learn about the memory safety mechanisms that are available in D.
Line 52: Line 52:
 test.d(10): Error: cannot take address of local a in @safe function main test.d(10): Error: cannot take address of local a in @safe function main
 </​code>​ </​code>​
 +
 +<note tip>
 +
 +For templated functions, the **@safe** attribute is inferred after the function has been generated
 +with the provided instantiation types. This means that a templated function can generate a **@safe**
 +function for one type and an un-**@safe** function for a different type.
 +
 +</​note>​
  
 ==== @trusted ==== ==== @trusted ====
Line 95: Line 103:
 **@system** is the default safety attribute for functions and it implies that no automatic safety checks are performed. **@system** is the default safety attribute for functions and it implies that no automatic safety checks are performed.
  
 +==== Type Qualifiers ====
 +
 +Type qualifiers modify a type by applying a type constructor. Type constructors are: **const**, **immutable**,​ **shared**, and **inout**. Each applies transitively to all subtypes.
 +
 +=== const/​immutable ===
 +When examining a data structure or interface, it is very helpful to be able to easily tell which data can be expected to not change, which data might change, and who may change that data. This is done with the aid of the language typing system. Data can be marked as **const** or **immutable**,​ with the default being changeable (or mutable).
 +
 +**1. immutable** applies to data that cannot change. Immutable data values, once constructed,​ remain the same for the duration of the program'​s execution. Immutable data can be placed in ROM (Read Only Memory) or in memory pages marked by the hardware as read only. Since immutable data does not change, it enables many opportunities for program optimization,​ and has applications in functional style programming.
 +
 +<code D>
 +immutable char[] s = "​foo";​
 +s[0] = '​a'; ​ // error, s refers to immutable data
 +s = "​bar"; ​  // error, s is immutable
 +
 +immutable int x = 3;  // x is set to 3
 +x = 4;        // error, x is immutable
 +char[x] z;    // z is an array of 3 chars
 +
 +immutable(char)[] s = "​hello";​
 +s[0] = '​b'; ​ // error, s[] is immutable
 +s = null;    // ok, s itself is not immutable
 +</​code>​
 +
 +**2. const** applies to data that cannot be changed by the const reference to that data. It may, however, be changed by another reference to that same data. Const finds applications in passing data through interfaces that promise not to modify them.
 +
 +<code D>
 +import std.stdio : writeln;
 +
 +int a;
 +
 +void gun()
 +{
 +    a = 10;
 +}
 +
 +void fun(const(int)* b)
 +{
 +    writeln(*b); ​    // prints 42
 +    gun();
 +    writeln(*b); ​    // prints 10
 +    *b = 3;          // error, cannot modify const expression *b                                                                                                                       
 +}
 +
 +void main()
 +{
 +    a = 42;
 +    fun(&​a);​
 +}
 +</​code>​
 +
 +Both **immutable** and **const** are transitive, which means that any data reachable through an **immutable** reference is also **immutable**,​ and likewise for **const**.
 +
 +== Implicit conversion rules ==
 +
 +1. Mutable data is implicitly convertible to **const**, but not to **immutable**.
 +
 +2. **const** data is not implicitly convertible to neither mutable, nor **immutable**.
 +
 +3. **immutable** data is implicitly convertible to **const**, but not to **mutable**.
 +
 +=== shared ===
 +
 +Unlike most other programming languages, data is not automatically shared in D;
 +data is thread-local by default. Although module-level variables may give the
 +impression of being accessible by all threads, each thread actually gets its own
 +copy:
 +
 +<code D>
 +import std.stdio;
 +import std.concurrency;​
 +import core.thread;​
 +
 +int variable;
 +void printInfo(string message)
 +{
 +    writefln("​%s:​ %s (@%s)",​ message, variable, &​variable);​
 +}
 +
 +void worker()
 +{
 +    variable = 42;
 +    printInfo("​Before the worker is terminated"​);​
 +}
 +
 +void main()
 +{
 +    spawn(&​worker);​
 +    thread_joinAll();​
 +    printInfo("​After the worker is terminated"​);​
 +}
 +</​code>​
 +
 +the variable that is modified inside **worker()** is not the same variable that is seen
 +by **main()**. Mutable variables that need to be shared must be defined with the shared
 +keyword:
 +
 +<code D>
 +shared int variable;
 +</​code>​
 +
 +On the other hand, since **immutable** variables cannot be modified, there is no
 +problem with sharing them directly. For that reason, **immutable** implies **shared**.
 +
 +===== Exercises =====
 +
 +The exercises for ''​lab-03''​ are located in this [[https://​github.com/​RazvanN7/​D-Summer-School/​tree/​master/​lab-03|repo]].
 +
 +==== 1. Qualifiers ====
 +
 +Navigate to the ''​1-qualifiers''​ directory. Read and understand the source file ''​qualifiers.d''​. Explain the working and the failing cases.
 +
 +==== 2. Qualified functions ====
 +
 +Navigate to the ''​2-qualfuncs''​ directory. Inspect the source file ''​qualfuncs.d''​. Should this code compile or not? Why?
 +
 +  * Add ''​immutable''​ at the end of the **foo** function signature.
 +<code D>
 +    void foo() immutable
 +</​code>​
 +  * What happens? How can this code be fixed? Ask the [[http://​ocw.cs.pub.ro/​courses/​dss?&#​team|lab rats]] for guidance.
 +
 +==== 3. Const ====
 +
 +Navigate to the ''​3-const''​ directory. Inspect the source file ''​const.d''​. Compile and run the code. Explain the results.
 +
 +==== 4. Array sort ====
 +
 +Implement a generic sorting algorithm for dynamic arrays.
 +
 +  * The arrays can be immutable/​const/​mutable.
 +  * The array element type can be any type that is ordering comparable.
 +  * The qualifier (mutable/​const/​immutabe) applies to both the array and the elements.
 +  * You must use template constraints and/or static ifs.
 +  * Recommendation:​ use 2 template overloads (one for mutable and one for const/​immutable);​ the mutable version does in-place sorting, the const/​immutable version creates a new array and returns it.
 +
 +==== 5. @safe ====
 +
 +Navigate to the  ''​5-safe''​ directory. Inspect the source file. Compile and run the code.
 +
 +  - What does the code do? Why is it useful to take the address of a parameter?
 +  - Add the **@safe** attribute to the **main** function. What happens?
 +  - Add **@safe** to the **func** and **gun** functions. Analyze the error messages.
 +  - How can we get rid of the first error message?
 +  - What about the second error message?
 +
 +==== 6. @trusted ====
 +
 +Navigate to the ''​6-trusted''​ directory. Inspect the source file. Compile and run the code.
 +
 +  - Is this code safe? Why?
 +  - Apply **@safe** to the **main** function. What happens? Why?
 +  - Move the **read** line in a new function, **safeRead**,​ that will be marked as **@trusted**.
 +
 +<note hint>
 +**@trusted** disables all the compiler checks for safety inside **@safe** functions. Be very careful when using it. With great power comes great responsibility.
 +</​note>​
 +
 +==== 7. Template attribute inference ====
 +
 +Navigate to the ''​7-template-inference''​ directory. Inspect the source file. Compile and run the code.
  
 +  - Add the **@safe** attribute to the **main** function. How do you explain the result? Why isn't the compiler complaining for the second invocation of func?
dss/laboratoare/03.1560424629.txt.gz ยท Last modified: 2019/06/13 14:17 by razvan.nitu1305
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0