forked from dlang/dlang.org
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdeprecate.dd
624 lines (496 loc) · 17.1 KB
/
deprecate.dd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
Ddoc
$(SPEC_S 廃止される機能,
$(P ある機能が悪いアイデアであった、と判明することはしばしばあります。
これらは $(I 廃止される機能) という扱いになり、
言語仕様から削除する方がよいと判断されると、
ユーザーが変更に対応する十分な時間をとるための手順を踏んで取り除かれます。
)
$(TABLE2 廃止される機能,
$(THEAD 機能, Spec, Warn, Dep, Error, Gone)
$(TROW $(DEPLINK 基底クラスのアクセス制御), 2.058, N/A, 2.058, , )
$(TROW $(DEPLINK 添字式での length の使用), ?, N/A, 2.041, , )
$(TROW $(DEPLINK typedef), 2.057, N/A, 2.057, , )
$(TROW $(DEPLINK 関数内での変数の隠蔽), ?, N/A, 0.161, , )
$(TROW $(DEPLINK immutableの別名としてのinvariant), 2.057, N/A, 2.057, , )
$(TROW $(DEPLINK 配列の * によるデリファレンス), ?, N/A, 2.057, , )
$(TROW $(DEPLINK delete による連想配列からの要素削除), ?, N/A, 0.127, , )
$(TROW $(DEPLINK .offset プロパティ), ?, N/A, 0.107, , )
$(TROW $(DEPLINK .size プロパティ), ?, N/A, 0.107, 0.107, )
$(TROW $(DEPLINK エスケープ文字列リテラル), ?, N/A, 2.026, , )
$(TROW $(DEPLINK 整数リテラルの小文字の 'l' 接尾辞), ?, N/A, 1.054, 0.174, )
$(TROW $(DEPLINK 8進リテラル), 2.054, N/A, 2.053, , )
$(TROW $(DEPLINK 虚数リテラルの大文字の 'I' 接尾辞), ?, N/A, 0.154, , )
$(TROW $(DEPLINK HTMLソースファイル), ?, N/A, 2.013, , )
$(TROW $(DEPLINK .typeinfo プロパティ), ?, N/A, 0.093, , )
$(TROW $(DEPLINK C形式の関数ポインタ), ?, N/A, 2.050, , )
$(TROW $(DEPLINK C形式の配列ポインタ), ?, N/A, 2.050, , )
$(TROW $(DEPLINK if (v; e)), ?, N/A, 0.149, 0.174, )
$(TROW $(DEPLINK volatile), 2.013, N/A, 2.013, , )
$(TROW $(DEPLINK default なしの final でない switch 文), 2.054, N/A, 2.054, , )
$(TROW $(DEPLINK 基底クラスの関数の隠蔽), 2.054, N/A, 2.054, , )
$(TROW $(DEPLINK Windows 3.x と Windows 9x 対応), 2.058, N/A, N/A, N/A, 2.058 )
$(TROW $(DEPLINK 浮動小数点型の .min プロパティ), 予定, , , , )
$(TROW $(DEPLINK 虚数型と複素数型), 予定, , , , )
$(TROW $(DEPLINK 浮動小数点数の NCEG 演算子), 予定, , , , )
$(TROW $(DEPLINK 配列の .sort と .reverse プロパティ), 予定, , , , )
$(TROW $(DEPLINK delete), 予定, , , , )
$(TROW $(DEPLINK overrideなしでのオーバーライド), 予定, , , , )
)
$(DL
$(DT Spec)
$(DD 仕様からの削除)
$(DT Warn)
$(DD 使われた場合にコンパイラが警告を出す)
$(DT Dep)
$(DD -d スイッチなしで使われた場合にコンパイラがエラーにする)
$(DT Error)
$(DD 使われた場合にコンパイラがエラーにする)
$(DT Gone)
$(DD 完全削除)
)
<h3>$(DEPNAME 基底クラスのアクセス制御)</h3>
基底クラスのアクセス制御とは次のようなものです:
---
class A : $(B protected) B {
...
}
---
<h4>修正方法</h4>
$(P 基底クラスの基底インターフェイスの前の、
アクセス保護属性キーワードを削除します。
)
<h4>理由</h4>
$(P Dのモジュールシステムの元では、これはあまり有用な使い道がなく、正しく動作したこともないため。
)
<h3>$(DEPNAME 添字式での length の使用)</h3>
配列のインデックスやスライス式の中では、length がその配列の長さに書き換えられていました。
---
auto a = new int[5];
a = a[0..length-1];
---
<h4>修正方法</h4>
$(P length を、同じ意味の $(LINK2 arrays.html#array-length, '$') に書き換えます。
)
<h4>理由</h4>
$(P 暗黙に定義される length が既存の宣言を隠すことがあり、また '$' と比べて冗長なため。
)
<h3>$(DEPNAME typedef)</h3>
typedef は型の強く区別される別名を作ることができました。
---
typedef int myint;
static assert(!is(myint == int));
---
<h4>修正方法</h4>
$(P typedef を alias に置き換えるか、$(FULL_STDREF typecons, Typedef) を使います。
)
<h4>理由</h4>
$(P typedef は全てのユースケースをカバーするほど柔軟ではなかったため。ライブラリによる解決を目指すべきです。
)
<h3>$(DEPNAME 関数内での変数の隠蔽)</h3>
内側のスコープで定義された変数が外側の変数と同じ名前を持つことがありました。
---
void myFun()
{
int var;
if (x)
{
int var;
var = 3; // どちらの var の意味?
}
}
---
<h4>修正方法</h4>
$(P 変数名を衝突しないように書き換えます。
)
<h4>理由</h4>
$(P 変数の隠蔽は、間違った変数を書き換えてしまうという発見の難しいバグをもたらすため。
)
<h3>$(DEPNAME immutableの別名としてのinvariant)</h3>
invariant 記憶域クラスは immutable の別名でした。
---
static assert(is(invariant(int) == immutable(int)));
---
<h4>修正方法</h4>
$(P 記憶域クラスや型修飾子としての invariant を immutable に置き換えます。構造体やクラスの不変条件のための invariant() 構文は依然として有効です。
)
<h4>理由</h4>
$(P 不要な別名なため。
)
<h3>$(DEPNAME 配列の * によるデリファレンス)</h3>
Dの配列変数は、ポインタのように先頭要素にアクセスすることができました。
---
int[] arr = [1, 2, 3];
assert(*arr == 1);
---
<h4>修正方法</h4>
$(P インデックス式を使います。
---
int[] arr = [1, 2, 3];
assert(arr[0] == 1);
---
)
<h4>理由</h4>
$(P Dの配列はポインタではないため。
)
<h3>$(DEPNAME delete による連想配列からの要素削除)</h3>
連想配列から要素を削除するのに delete 式が使えました。
---
int[int] aa = [1 : 2];
delete aa[1];
assert(1 !in aa);
---
<h4>修正方法</h4>
$(P .remove を代わりに使います。
---
int[int] aa = [1 : 2];
aa.remove(1);
assert(1 !in aa);
---
)
<h4>理由</h4>
$(P delete 構文は混乱を招きやすく、また通常の delete 構文とも衝突するため。
)
<h3>$(DEPNAME .offset プロパティ)</h3>
.offset プロパティはメンバのオフセット情報を取得するのに使えました。
---
struct S { int a, b; }
static assert(S.b.offset == 4);
---
<h4>修正方法</h4>
$(P .offsetof を代わりに使います。
---
struct S { int a, b; }
static assert(S.b.offsetof == 4);
---
)
<h4>理由</h4>
$(P .offset は .offsetof に変更されたため。
)
<h3>$(DEPNAME .size プロパティ)</h3>
.size プロパティは型のサイズ情報を取得するのに使えました。
---
struct S { int a, b; }
static assert(S.size == 8);
---
<h4>修正方法</h4>
$(P .sizeof を代わりに使います。
---
struct S { int a, b; }
static assert(S.sizeof == 8);
---
)
<h4>理由</h4>
$(P .size は .sizeof に変更されたため。
)
<h3>$(DEPNAME エスケープ文字列リテラル)</h3>
エスケープシーケースをそのまま書いて文字列リテラルとして使うことができました。
---
string x = "hello" ~ \n;
---
<h4>修正方法</h4>
$(P エスケープシーケンスを普通の文字列リテラルの中に入れます。
---
string x = "hello\n";
---
)
<h4>理由</h4>
$(P エスケープ文字列リテラルは非直感的かつ必要でもないため。
)
<h3>$(DEPNAME 整数リテラルの小文字の 'l' 接尾辞)</h3>
小文字の 'l' で整数リテラルの型が64bit整数であることを示すことができました。
---
auto x = 123l;
---
<h4>修正方法</h4>
$(P 大文字の 'L' 接尾辞を使います。
---
auto x = 123L;
---
)
<h4>理由</h4>
$(P 小文字は数字の '1' と紛らわしいため。
)
<h3>$(DEPNAME 8進リテラル)</h3>
八進数で整数リテラルを記述できました。
---
auto x = 0123;
---
<h4>修正方法</h4>
$(P octal!num テンプレートを使います。
---
auto x = octal!123;
---
)
<h4>理由</h4>
$(P 0123 != 123 など、先頭 0 は区別するのは混乱の元なため。
)
<h3>$(DEPNAME 虚数リテラルの大文字の 'I' 接尾辞)</h3>
大文字の 'I' でリテラルが虚数型であることを示すことができました。
---
auto x = 1.234I;
---
<h4>修正方法</h4>
$(P 小文字の 'i' を使います。
---
auto x = 1.234i;
---
)
<h4>理由</h4>
$(P 大文字は数字の '1' と紛らわしいため。
)
<h3>$(DEPNAME HTMLソースファイル)</h3>
DコンパイラはHTMLファイルを構文解析して <code></code> タグの中だけをDのコードとして解釈することができました。
---
<html>
<code>
... ソース ...
</code>
</html>
---
<h4>修正方法</h4>
$(P 普通のソースとしてコードを抽出します。
)
<h4>理由</h4>
$(P ドキュメントを添える機能は、ddoc によるドキュメント化コメントによって置き換えられたため。
)
<h3>$(DEPNAME .typeinfo プロパティ)</h3>
.typeinfo プロパティによってその型の TypeInfo クラスにアクセスできました。
---
T.typeinfo
---
<h4>修正方法</h4>
$(P typeid() を代わりに使います。
---
typeid(T)
---
)
<h4>理由</h4>
$(P .typeinfo は typeid() に変更になったため。
)
<h3>$(DEPNAME C形式の関数ポインタ)</h3>
C形式の関数ポインタをDでも使うことができました。
---
alias void(*fptr)(int, long);
---
<h4>修正方法</h4>
$(P D形式の関数ポインタに置き換えます。
---
alias void function(int, long) fptr;
---
)
<h4>理由</h4>
$(P D形式の方がずっと綺麗で使いやすいため。
)
<h3>$(DEPNAME C形式の配列ポインタ)</h3>
C形式の配列ポインタをDでも使うことができました。
---
alias float *arrayptr[10][15];
---
<h4>修正方法</h4>
$(P D形式の配列ポインタに置き換えます。
---
alias float[15][10]* arrayptr;
---
)
<h4>理由</h4>
$(P D形式の方がずっと綺麗で使いやすいため。
)
<h3>$(DEPNAME if (v; e))</h3>
この構文では if の条件部で変数宣言を導入できました。
---
if (v; calculateAndReturnPointer()) { ... }
---
<h4>修正方法</h4>
$(P auto 宣言で置き換えます。
---
if (auto v = calculateAndReturnPointer()) { ... }
---
)
<h4>理由</h4>
$(P auto があった方が構文の意図が明確なため。
)
<h3>$(DEPNAME volatile)</h3>
volatile で文をマークすることで、ある種のコンパイラの最適化を抑止できました。
---
volatile
{
... 共有変数を触る処理 ...
}
---
<h4>修正方法</h4>
$(P コードを synchronized 文に書き換えます。
)
<h4>理由</h4>
$(P volatile 文は誤りでした。
)
<h3>$(DEPNAME default なしの final でない switch 文)</h3>
switch 文は default ケースなしで宣言でき、その場合がコンパイラが自動で補っていました。
---
switch(a)
{
case 1:
break;
case 2:
break;
// コンパイラが自動で追加
// default:
// throw new SwitchError();
}
---
<h4>修正方法</h4>
$(P default を手で明示します。
---
switch(a)
{
case 1:
break;
case 2:
break;
default:
assert(0);
}
---
)
<h4>理由</h4>
$(P default 抜けはバグを隠すことがあるため、明示することを義務化しました。
)
<h3>$(DEPNAME 基底クラスの関数の隠蔽)</h3>
基底クラスのものと同じ引数で呼び出せるのにもかかわらず、オーバーライドにはなっていないような派生クラスの関数が、基底クラスの関数を隠蔽することがありました。
---
class A
{
void fun(int x) {}
}
class B : A
{
void fun(long x) {}
}
---
<h4>修正方法</h4>
$(P 基底クラスに関数を追加するか、alias を使って派生クラスでオーバーロードを行います。
---
class A
{
void fun(int x) {}
void fun(long x) {} // this fixes it
}
class B : A
{
void fun(long x) {}
alias A.fun fun; // so does this
}
---
)
<h4>理由</h4>
$(P これは実行時に元々エラーとして検出されていましたが、コンパイル時エラーとしました。
)
<h3>$(DEPNAME Windows 3.x と Windows 9x 対応)</h3>
Phobos には Windows 3.x/9x 対応のコードが含まれていました。
<h4>修正方法</h4>
$(P Windows をバージョンアップするか、他の対応OSに移行します。
)
<h4>理由</h4>
$(P このような古く、もうほとんど使われないOSのサポートを続けるのは労力に見合わないため。
)
<h3>$(DEPNAME 浮動小数点型の .min プロパティ)</h3>
浮動小数点型にはその最小値にアクセスする .min プロパティがあります。
---
enum m = real.min;
---
<h4>修正方法</h4>
$(P .min_normal に置き換え。
---
enum m = real.min_normal;
---
)
<h4>理由</h4>
$(P .min には非正規化数を含まない ので、min_normal という名前の方がより正確なため。
)
<h3>$(DEPNAME 虚数型と複素数型)</h3>
Dは組み込みで虚数と複素数型を持っています。
---
float a = 2;
ifloat b = 4i;
cfloat c = a + b;
assert(c == 2 + 4i);
---
<h4>修正方法</h4>
$(P $(STDFILEREF complex) ライブラリの型を使用します。
)
<h4>理由</h4>
$(P これらの型はコア言語の一部として持つには特殊すぎるため。
)
<h3>$(DEPNAME 浮動小数点数の NCEG 演算子)</h3>
D は現在のところ NCEG 浮動小数点演算子 (!<>=, <>, <>=, !>, !>=, !<, !<=, !<>) を、NaN の関わる比較のために提供しています。
<h4>修正方法</h4>
$(P 普通の比較演算子と $(FULL_STDREF math, isNaN) を使います。
)
<h4>理由</h4>
$(P これらの演算子はコア言語の一部として持つには特殊すぎるため。
)
<h3>$(DEPNAME 配列の .sort と .reverse プロパティ)</h3>
D の配列はこれら組み込みで操作することができます。
---
int[] x = [2, 3, 1];
assert(x.sort == [1, 2, 3]);
---
<h4>修正方法</h4>
$(P $(STDFILEREF algorithm) の汎用関数を使います。
)
<h4>理由</h4>
$(P これらの操作は標準ライブラリでよりよく実装されているため。
)
<h3>$(DEPNAME delete)</h3>
GCヒープに割り当てたメモリを delete で解放できます。
---
auto a = new Class();
delete a;
---
<h4>修正方法</h4>
$(P object.clear() を代わりに使います。
---
auto a = new Class();
clear(a);
---
)
<h4>理由</h4>
$(P delete はガベージコレクタの種類に対するある種の仮定なしには実現できません。これは実装の自由度を制約してしまうため、ライブラリによる方法に置き換えられていくべきです。
)
<h3>$(DEPNAME overrideなしでのオーバーライド)</h3>
現在のところ、仮想関数は 'override' 属性なしで基底クラスの関数をオーバーライドできます。
---
class A
{
void fun() {}
}
class B : A
{
// override なしでのオーバーライド
void fun() {}
}
---
<h4>修正方法</h4>
$(P 'override' で明示的にマークします。
---
class A
{
void fun() {}
}
class B : A
{
override void fun() {}
}
---
)
<h4>理由</h4>
$(P 'override' 属性でのマーク付けを義務化することでコードが明確になり、また、うっかり基底クラスの関数をオーバーライドしてしまう間違いも検出可能になります。
)
)
Macros:
DEPLINK=$(LINK2 #$0, $0)
DEPLINK2=$(LINK2 $1.html#$2, $2)
DEPNAME=$(LNAME2 $0, $0)
TITLE=廃止される機能
WIKI=DeprecatedFeatures
FULL_STDREF = <a href="phobos/std_$1.html#$2">$(D std.$1.$2)</a>
STDFILEREF = <a href="phobos/std_$1.html">$(D std.$1)</a>