You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: ownership.md
+57-20Lines changed: 57 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -96,13 +96,40 @@ This warning relies on flow analysis, which ensures that the potential nullabili
96
96
#### Non nullable members
97
97
98
98
The concept of nullable types is present in some language like C# and Typescript.
99
-
Both languages have the concept of `constructor` for objects. So, for objects members, the compiler checks if after the constructor the non-nullable members have being assigned to a non null value.
99
+
Both languages have the concept of object constructor. For object members, the compiler checks if
100
+
after the constructor the non-nullable members have being assigned to a non null value.
100
101
101
-
The other way to see this, is that during construction the non nullable pointer member can be null, before they receive a value.
102
+
For instance, in Typescript
102
103
103
-
In C, we don t have the concept of constructor, so the same approach cannot be applied directly.
104
+
```ts
105
+
classY {
106
+
public i =0;
107
+
}
108
+
109
+
classX
110
+
{
111
+
publicreadonly i :number;
112
+
public pY :Y;
113
+
constructor(){
114
+
//Property 'pY' has no initializer and is not definitely assigned
The particular instance of p, that has being qualified with \_Opt, is allowed to have no-nullable members with a null values.
128
157
129
-
Just like in C# or Typescript, we cannot leave this function with a nullable member being null. But the particular instance of p is allowed to have nullable members.
158
+
However, we cannot leave this function with a non-nullable member being null because the result of
159
+
the function is not \_Opt qualified.
160
+
This approach makes it possible to have an alternative design for constructors.
130
161
131
-
This is also useful to accept for some functions like destructor, partially constructed object.
162
+
This state is also useful for some functions like destructor, to be able to destroy partially constructed objects.
163
+
For instance:
132
164
133
165
```c
134
166
void x_destroy(_Opt struct X * p)
@@ -137,9 +169,16 @@ void x_destroy(_Opt struct X * p)
137
169
}
138
170
```
139
171
172
+
>Note : This design may change and be replaced by mutable.
173
+
174
+
#### mutable
175
+
140
176
Note that this concept also could be applied for const members.
141
177
142
-
The introduction of a **mutable** qualifier allows certain exceptions to the usual contract of immutability and non-nullability during transitional phases, such as in constructors and destructors. This means that objects marked as **mutable** can temporarily violate their normal constraints, such as modifying `const` members or assigning null to non-nullable pointers during these phases.
178
+
The introduction of a **mutable** qualifier allows certain exceptions to the usual contract
179
+
of immutability and non-nullability during transitional phases, such as in constructors and destructors.
180
+
This means that objects marked as **mutable** can temporarily violate their normal constraints,
181
+
such as modifying `const` members or assigning null to non-nullable pointers during these phases.
In this example, `struct X` has a `const` member `name`, which is non-nullable. Under normal conditions, modifying a `const` member after initialization would be disallowed. However, the **mutable** qualifier temporarily relaxes this rule during the object’s creation process, allowing modifications even to `const` members, and allowing a non-nullable pointer to be null before the object’s initialization completes.
205
+
In this example, `struct X` has a `const` member `name`, which is non-nullable.
206
+
Under normal conditions, modifying a `const` member after initialization would be disallowed.
207
+
208
+
However, the **mutable** qualifier temporarily relaxes this rule during the object’s creation process,
209
+
allowing modifications even to `const` members, and allowing a non-nullable pointer to be null
210
+
before the object’s initialization completes.
167
211
168
-
We also have an implicit contract for struct members. Generally, we assume that members are initialized, but we lack a qualifier to explicitly indicate "initialized member." For instance, when using malloc, members are initially uninitialized, but they should receive a value before being used.
212
+
We also have an implicit contract for struct members.
213
+
Generally, we assume that members are initialized, but we lack a qualifier to explicitly
214
+
indicate "initialized member."
215
+
For instance, when using malloc, members are initially uninitialized, but they should receive a value before being used.
During the object creation (or destruction), the instance is considered to be in a transitional state, where the usual constraints—such as non-nullable pointers and immutability—are lifted. For example, in the `makeX` function, `p->name` can be set to `temp`, even though `name` is `const`. This allows flexibility during initialization, after which the object is returned to its normal state with the contract fully enforced.
190
-
191
-
##### Effect on the Final Object:
192
-
Once the transitional phase is over and the object is returned, the contract that governs the object (such as immutability of `name` and non-nullability of pointers) is fully reinstated. The **mutable** qualifier only applies within the scope of the constructor or destructor, ensuring that once the object is fully constructed, its state is valid and consistent with the type system’s rules.
193
-
194
-
This approach allows for more flexibility during object creation while maintaining strong contracts once the object is finalized, enhancing both safety and expressiveness in the code.
195
-
196
-
197
-
OBS: mutable qualifier is not yet implemented in Cake. However, _Opt for structs is implemented.
234
+
>OBS: mutable qualifier is not yet implemented in Cake. However, _Opt for structs is implemented and may be replaced in the future
Copy file name to clipboardExpand all lines: src/web/ownership.html
+58-20Lines changed: 58 additions & 20 deletions
Original file line number
Diff line number
Diff line change
@@ -147,13 +147,37 @@ <h4>Example 3: Diagnostic for Nullable to Non-Nullable Conversion</h4>
147
147
<h4>Non nullable members</h4>
148
148
149
149
<p>The concept of nullable types is present in some language like C# and Typescript.
150
-
Both languages have the concept of <code>constructor</code> for objects. So, for objects members, the compiler checks if after the constructor the non-nullable members have being assigned to a non null value.</p>
150
+
Both languages have the concept of object constructor. For object members, the compiler checks if
151
+
after the constructor the non-nullable members have being assigned to a non null value.</p>
151
152
152
-
<p>The other way to see this, is that during construction the non nullable pointer member can be null, before they receive a value.</p>
153
+
<p>For instance, in Typescript</p>
153
154
154
-
<p>In C, we don t have the concept of constructor, so the same approach cannot be applied directly.</p>
155
+
<pre><codeclass="language-ts">class Y {
156
+
public i = 0;
157
+
}
158
+
159
+
class X
160
+
{
161
+
public readonly i : number;
162
+
public pY : Y;
163
+
constructor(){
164
+
//Property 'pY' has no initializer and is not definitely assigned
165
+
//in the constructor.(2564)
166
+
//this.pY = new Y;
167
+
//this.i = 1;
168
+
}
169
+
}
170
+
171
+
</code></pre>
155
172
156
-
<p>Cake, have a mechanism using the qualifier <code>_Opt</code> before struct types to make all non-nullable members as nullable for a particular instance.</p>
<p>The other way to see this, is that during construction the invariant of the object is not complete yet.</p>
176
+
177
+
<p>In C, we don t have the concept of constructor, so the same approach cannot be applied directly.</p>
178
+
179
+
<p>Cake, have a mechanism using the qualifier <code>_Opt</code> before struct types to make all non-nullable members as nullable for a particular instance.
180
+
This allow us the have a object where the invariant is not completed.</p>
<p>Just like in C# or Typescript, we cannot leave this function with a nullable member being null. But the particular instance of p is allowed to have nullable members.</p>
203
+
<p>The particular instance of p, that has being qualified with _Opt, is allowed to have no-nullable members with a null values.</p>
180
204
181
-
<p>This is also useful to accept for some functions like destructor, partially constructed object.</p>
205
+
<p>However, we cannot leave this function with a non-nullable member being null because the result of
206
+
the function is not _Opt qualified.
207
+
This approach makes it possible to have an alternative design for constructors.</p>
208
+
209
+
<p>This state is also useful for some functions like destructor, to be able to destroy partially constructed objects.
210
+
For instance:</p>
182
211
183
212
<pre><codeclass="language-c">void x_destroy(_Opt struct X * p)
184
213
{
185
214
free(p->name); //ok
186
215
}
187
216
</code></pre>
188
217
218
+
<blockquote>
219
+
<p>Note : This design may change and be replaced by mutable.</p>
220
+
</blockquote>
221
+
222
+
<h4>mutable</h4>
223
+
189
224
<p>Note that this concept also could be applied for const members. </p>
190
225
191
-
<p>The introduction of a <strong>mutable</strong> qualifier allows certain exceptions to the usual contract of immutability and non-nullability during transitional phases, such as in constructors and destructors. This means that objects marked as <strong>mutable</strong> can temporarily violate their normal constraints, such as modifying <code>const</code> members or assigning null to non-nullable pointers during these phases.</p>
226
+
<p>The introduction of a <strong>mutable</strong> qualifier allows certain exceptions to the usual contract
227
+
of immutability and non-nullability during transitional phases, such as in constructors and destructors.
228
+
This means that objects marked as <strong>mutable</strong> can temporarily violate their normal constraints,
229
+
such as modifying <code>const</code> members or assigning null to non-nullable pointers during these phases.</p>
<p>In this example, <code>struct X</code> has a <code>const</code> member <code>name</code>, which is non-nullable. Under normal conditions, modifying a <code>const</code> member after initialization would be disallowed. However, the <strong>mutable</strong> qualifier temporarily relaxes this rule during the object’s creation process, allowing modifications even to <code>const</code> members, and allowing a non-nullable pointer to be null before the object’s initialization completes.</p>
252
+
<p>In this example, <code>struct X</code> has a <code>const</code> member <code>name</code>, which is non-nullable.
253
+
Under normal conditions, modifying a <code>const</code> member after initialization would be disallowed. </p>
215
254
216
-
<p>We also have an implicit contract for struct members. Generally, we assume that members are initialized, but we lack a qualifier to explicitly indicate "initialized member." For instance, when using malloc, members are initially uninitialized, but they should receive a value before being used.</p>
255
+
<p>However, the <strong>mutable</strong> qualifier temporarily relaxes this rule during the object’s creation process,
256
+
allowing modifications even to <code>const</code> members, and allowing a non-nullable pointer to be null
257
+
before the object’s initialization completes.</p>
258
+
259
+
<p>We also have an implicit contract for struct members.
260
+
Generally, we assume that members are initialized, but we lack a qualifier to explicitly
261
+
indicate "initialized member."
262
+
For instance, when using malloc, members are initially uninitialized, but they should receive a value before being used.</p>
217
263
218
264
<pre><codeclass="language-c">struct X * _Opt makeX(const char* name)
<p>During the object creation (or destruction), the instance is considered to be in a transitional state, where the usual constraints—such as non-nullable pointers and immutability—are lifted. For example, in the <code>makeX</code> function, <code>p->name</code> can be set to <code>temp</code>, even though <code>name</code> is <code>const</code>. This allows flexibility during initialization, after which the object is returned to its normal state with the contract fully enforced.</p>
237
-
238
-
<h5>Effect on the Final Object:</h5>
239
-
240
-
<p>Once the transitional phase is over and the object is returned, the contract that governs the object (such as immutability of <code>name</code> and non-nullability of pointers) is fully reinstated. The <strong>mutable</strong> qualifier only applies within the scope of the constructor or destructor, ensuring that once the object is fully constructed, its state is valid and consistent with the type system’s rules.</p>
241
-
242
-
<p>This approach allows for more flexibility during object creation while maintaining strong contracts once the object is finalized, enhancing both safety and expressiveness in the code.</p>
243
-
244
-
<p>OBS: mutable qualifier is not yet implemented in Cake. However, _Opt for structs is implemented.</p>
280
+
<blockquote>
281
+
<p>OBS: mutable qualifier is not yet implemented in Cake. However, _Opt for structs is implemented and may be replaced in the future</p>
0 commit comments