565 changes: 557 additions & 8 deletions deprecate.dd
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,34 @@ $(SPEC_S Deprecated Features,
)

$(TABLE2 Deprecated Features,
$(THEAD Feature, Spec, Warn, Dep, Error, Gone)
$(TROW $(DEPLINK Base Class Protection), 2.058,  ,  ,  ,  )
$(THEAD Feature, Spec, Warn, Dep, Error, Gone)
$(TROW $(DEPLINK Base Class Protection), 2.058, N/A, 2.058,  ,  )
$(TROW $(DEPLINK Using length in index expressions), ?, N/A, 2.041,  ,  )
$(TROW $(DEPLINK typedef), 2.057, N/A, 2.057,  ,  )
$(TROW $(DEPLINK Variable shadowing inside functions), ?, N/A, 0.161,  ,  )
$(TROW $(DEPLINK invariant as an alias for immutable), 2.057, N/A, 2.057,  ,  )
$(TROW $(DEPLINK Using * to dereference arrays), ?, N/A, 2.057,  ,  )
$(TROW $(DEPLINK Removing an item from an associative array with delete), ?, N/A, 0.127,  ,  )
$(TROW $(DEPLINK .offset property), ?, N/A, 0.107,  ,  )
$(TROW $(DEPLINK Escape string literals), ?, N/A, 2.026,  ,  )
$(TROW $(DEPLINK Lower case 'l' suffix for integer literals), ?, N/A, 1.054, 1.074,  )
$(TROW $(DEPLINK Octal literals), 2.054, N/A, 2.053,  ,  )
$(TROW $(DEPLINK Upper case 'I' suffix for imaginary literals), ?, N/A, 0.154,  ,  )
$(TROW $(DEPLINK HTML source files), ?, N/A, 2.013,  ,  )
$(TROW $(DEPLINK .typeinfo property), ?, N/A, 0.093,  ,  )
$(TROW $(DEPLINK C-style function pointers), ?, N/A, 2.050,  ,  )
$(TROW $(DEPLINK C-style array pointers), ?, 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 Non-final switch statements without a default case), 2.054, N/A, 2.054,  ,  )
$(TROW $(DEPLINK Hiding base class functions), 2.054, N/A, 2.054,  ,  )

$(TROW $(DEPLINK .min property for floating point types), future,  ,  ,  ,  )
$(TROW $(DEPLINK imaginary and complex types), future,  ,  ,  ,  )
$(TROW $(DEPLINK floating point NCEG operators), future,  ,  ,  ,  )
$(TROW $(DEPLINK .sort and .reverse properties for arrays), future,  ,  ,  ,  )
$(TROW $(DEPLINK delete), future,  ,  ,  ,  )
$(TROW $(DEPLINK overriding without override), future,  ,  ,  ,  )
)

$(DL
Expand All @@ -24,27 +50,550 @@ $(SPEC_S Deprecated Features,
$(DD It is an error to use the feature)
$(DT Gone)
$(DD The feature is completely gone)
)
)


<h3>$(DEPNAME Base Class Protection)</h3>

Base class protections are things like:

<h3>$(DEPNAME Base Class Protection)</h3>
Base class protections are things like:
---
class A : $(B protected) B {
...
}
---

<h4>Corrective Action</h4>

$(P Delete the protection attribute keyword from in front of the base class
and base interfaces.
)
<h4>Rationale</h4>
$(P With D's module system, it doesn't seem to serve any useful purpose, and has never worked correctly.
)



<h3>$(DEPNAME Using length in index expressions)</h3>
When used inside an indexing or slicing expression, length is rewritten to be the length of the array being sliced.
---
auto a = new int[5];
a = a[0..length-1];
---
<h4>Corrective Action</h4>
$(P Replace length with the equivalent $(LINK2 arrays.html#array-length, '$')
)
<h4>Rationale</h4>
$(P The implicitly defined length variable shadows existing declarations, and is less concise than the alternative.
)



<h3>$(DEPNAME typedef)</h3>
typedef can be used to construct a strongly-typed alias of a type.
---
typedef int myint;
static assert(!is(myint == int));
---
<h4>Corrective Action</h4>
$(P Replace use of typedef with alias.
)
<h4>Rationale</h4>
$(P typedef is not flexible enough to cover all use cases. This is better done with a library solution.
)





<h3>$(DEPNAME Variable shadowing inside functions)</h3>
Variable shadowing is when a variable in an inner scope has the same name as a variable in an enclosing scope.
---
void myFun()
{
int var;
if (x)
{
int var;
var = 3; // which var was meant?
}
}
---
<h4>Corrective Action</h4>
$(P Rename shadowing variables so they don't conflict.
)
<h4>Rationale</h4>
$(P Variable shadowing can introduce hard to find bugs where the wrong variable is modified.
)





<h3>$(DEPNAME invariant as an alias for immutable)</h3>
The invariant storage class and type modifier is an alias for immutable.
---
static assert(is(invariant(int) == immutable(int)));
---
<h4>Corrective Action</h4>
$(P Replace all uses of invariant as a storage class or type modifier with immutable. The invariant() syntax for struct and class invariants is still supported.
)
<h4>Rationale</h4>
$(P The alias is unnecessary.
)






<h3>$(DEPNAME Using * to dereference arrays)</h3>
D array variables can be dereferenced to get the first element, much like pointers.
---
int[] arr = [1, 2, 3];
assert(*arr == 1);
---
<h4>Corrective Action</h4>
$(P Use indexing syntax to access first member.
---
int[] arr = [1, 2, 3];
assert(arr[0] == 1);
---
)
<h4>Rationale</h4>
$(P D arrays are not pointers.
)




<h3>$(DEPNAME Removing an item from an associative array with delete)</h3>
delete can be used to remove an item from an associative array.
---
int[int] aa = [1 : 2];
delete aa[1];
assert(1 !in aa);
---
<h4>Corrective Action</h4>
$(P Use .remove instead.
---
int[int] aa = [1 : 2];
aa.remove(1);
assert(1 !in aa);
---
)
<h4>Rationale</h4>
$(P The delete syntax is confusing and conflicts with the normal delete syntax.
)





<h3>$(DEPNAME .offset property)</h3>
The .offset property can be used to get member offset information.
---
struct S { int a, b; }
static assert(S.b.offset == 4);
---
<h4>Corrective Action</h4>
$(P Use .offsetof instead
---
struct S { int a, b; }
static assert(S.b.offsetof == 4);
---
)
<h4>Rationale</h4>
$(P The .offset syntax has been superseded by .offsetof
)




<h3>$(DEPNAME Escape string literals)</h3>
Escape string literals can be used to describe characters using escape sequences.
---
string x = "hello" ~ \n;
---
<h4>Corrective Action</h4>
$(P Put escape sequences inside a regular string literal.
---
string x = "hello\n";
---
)
<h4>Rationale</h4>
$(P Escape string literals are unintuitive and unnecessary.
)




<h3>$(DEPNAME Lower case 'l' suffix for integer literals)</h3>
Lower case 'l' is an alternative suffix to denote 64 bit integer literals.
---
auto x = 123l;
---
<h4>Corrective Action</h4>
$(P Use the upper case 'L' suffix.
---
auto x = 123L;
---
)
<h4>Rationale</h4>
$(P The lower case suffix is easily confused with the digit '1'.
)




<h3>$(DEPNAME Octal literals)</h3>
Octal literals can be used to enter literals in base 8.
---
auto x = 0123;
---
<h4>Corrective Action</h4>
$(P Use the octal!num template.
---
auto x = octal!123;
---
)
<h4>Rationale</h4>
$(P The use of a leading zero is confusing, as 0123 != 123.
)





<h3>$(DEPNAME Upper case 'I' suffix for imaginary literals)</h3>
The 'I' suffix can be used to denote imaginary floating point values.
---
auto x = 1.234I;
---
<h4>Corrective Action</h4>
$(P Use the lower case 'i' suffix.
---
auto x = 1.234i;
---
)
<h4>Rationale</h4>
$(P The 'I' suffix is easily confused with the digit '1'.
)





<h3>$(DEPNAME HTML source files)</h3>
The D compiler can parse html files by ignoring everything not contained in &lt;code&gt&lt/code&gt tags.
---
<html>
<code>
... source ...
</code>
</html>
---
<h4>Corrective Action</h4>
$(P Extract code to regular source files.
)
<h4>Rationale</h4>
$(P This has been replaced for documentation by the introduction of ddoc
)





<h3>$(DEPNAME HTML source files)</h3>
The D compiler can parse html files by ignoring everything not contained in &lt;code&gt&lt/code&gt tags.
---
<html>
<code>
... source ...
</code>
</html>
---
<h4>Corrective Action</h4>
$(P Extract code to regular source files.
)
<h4>Rationale</h4>
$(P This has been replaced for documentation by the introduction of ddoc
)




<h3>$(DEPNAME .typeinfo property)</h3>
The .typeinfo property can be used to get the associated TypeInfo class.
---
T.typeinfo
---
<h4>Corrective Action</h4>
$(P Use .typeid instead
---
T.typeid
---
)
<h4>Rationale</h4>
$(P The .typeinfo syntax has been superseded by .typeid
)




<h3>$(DEPNAME C-style function pointers)</h3>
C-style function pointers can be used in D.
---
alias void(*fptr)(int, long);
---
<h4>Corrective Action</h4>
$(P Replace with D-style function pointers.
---
alias void function(int, long) fptr;
---
)
<h4>Rationale</h4>
$(P The D syntax is much cleaner and easier to use.
)



<h3>$(DEPNAME C-style array pointers)</h3>
C-style array pointers can be used in D.
---
alias float *arrayptr[10][15];
---
<h4>Corrective Action</h4>
$(P Replace with D-style array pointers.
---
alias float[15][10]* arrayptr;
---
)
<h4>Rationale</h4>
$(P The D syntax is much cleaner and easier to use.
)




<h3>$(DEPNAME if (v; e))</h3>
This syntax can be used to declare a variable in an if statement condition.
---
if (v; calculateAndReturnPointer()) { ... }
---
<h4>Corrective Action</h4>
$(P Replace with an auto declaration.
---
if (auto v = calculateAndReturnPointer()) { ... }
---
)
<h4>Rationale</h4>
$(P The syntax is clearer with auto.
)



<h3>$(DEPNAME volatile)</h3>
volatile can be used to mark statement, in order to prevent some compiler optimizations.
---
volatile
{
... do something involving ghared variables ...
}
---
<h4>Corrective Action</h4>
$(P Convert the code to use synchronized statements instead.
)
<h4>Rationale</h4>
$(P volatile statements are a misfeature.
)




<h3>$(DEPNAME Non-final switch statements without a default case)</h3>
Switch statements can be declared without a default case, and the compiler automatically adds one.
---
switch(a)
{
case 1:
break;
case 2:
break;
// the compiler adds
// default:
// throw new SwitchError();
}
---
<h4>Corrective Action</h4>
$(P Add the default case manually.
---
switch(a)
{
case 1:
break;
case 2:
break;
default:
assert(0);
}
---
)
<h4>Rationale</h4>
$(P Missing default cases can hide bugs, and making the default case explicit should be mandatory.
)




<h3>$(DEPNAME Hiding base class functions)</h3>
Declaration functions in a derived class that can be called with the same arguments as a function in a base class, but do not override that function causes the base class function to be hidden.
---
class A
{
void fun(int x) {}
}
class B : A
{
void fun(long x) {}
}
---
<h4>Corrective Action</h4>
$(P Add the function to the base class, or use an alias to bring the base class overload into the derived class.
---
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>Rationale</h4>
$(P This is an error that is already detected at runtime, and is being extended to compile time.
)



<h3>$(DEPNAME .min property for floating point types)</h3>
Floating point types have the .min property to access the smallest value.
---
enum m = real.min;
---
<h4>Corrective Action</h4>
$(P Replace with .min_normal
---
enum m = real.min_normal;
---
)
<h4>Rationale</h4>
$(P The name min_normal is more accurate, as .min does not include denormalized floating point values.
)


<h3>$(DEPNAME imaginary and complex types)</h3>
D currently supports imaginary and complex versions of all floating point types.
---
float a = 2;
ifloat b = 4i;
cfloat c = a + b;
assert(c == 2 + 4i);
---
<h4>Corrective Action</h4>
$(P Use the library types in std.complex
)
<h4>Rationale</h4>
$(P These types are too specialized to be a part of the core lanugage.
)





<h3>$(DEPNAME floating point NCEG operators)</h3>
D currently the NCEG floating point operators (!<>=, <>, <>=, !>, !>=, !<, !<=, !<>) for comparisons involving NaNs.
<h4>Corrective Action</h4>
$(P Use the normal operators and std.math.isNaN.
)
<h4>Rationale</h4>
$(P These operators are too specialized to be a part of the core lanugage.
)





<h3>$(DEPNAME .sort and .reverse properties for arrays)</h3>
D arrays can be manipulated using these built-in properties.
---
int[] x = [2, 3, 1];
assert(x.sort == [1, 2, 3]);
---
<h4>Corrective Action</h4>
$(P Use the generic functions in std.algorithm
)
<h4>Rationale</h4>
$(P These operations are better implemented in the standard library
)





<h3>$(DEPNAME delete)</h3>
Memory allocated on the GC heap can be freed with delete.
---
auto a = new Class();
delete a;
---
<h4>Corrective Action</h4>
$(P Use object.clear() instead.
---
auto a = new Class();
clear(a);
---
)
<h4>Rationale</h4>
$(P delete makes assumptions about the type of garbage collector available that limits which implementations can be used, and can be replaced by a library solution.
)





<h3>$(DEPNAME overriding without override)</h3>
Virtual functions can currently override a function in a base class without the 'override' attribute.
---
class A
{
void fun() {}
}
class B : A
{
// overrides but is not marked with override
void fun() {}
}
---
<h4>Corrective Action</h4>
$(P Mark overriding functions with 'override'
---
class A
{
void fun() {}
}
class B : A
{
override void fun() {}
}
---
)
<h4>Rationale</h4>
$(P Making the 'override' attribute mandatory makes it explicit, and can catch errors when a base class function is accidentally overridden.
)


$(P With D's module system, it doesn't seem to serve any useful purpose.)

)

Expand Down
2 changes: 1 addition & 1 deletion type.dd
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ $(SECTION2 Implicit Conversions,
$(P A $(V1 typedef or) enum can be implicitly converted to its base
type, but going the other way requires an explicit
conversion.
A literal can be implicitly converted to a typedef.
$(V1 A literal can be implicitly converted to a typedef.)
For example:
)

Expand Down
6 changes: 4 additions & 2 deletions win32.mak
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SRC= $(SPECSRC) cpptod.dd ctod.dd pretod.dd cppdbc.dd index.dd \
template-comparison.dd COM.dd hijack.dd features2.dd safed.dd \
const-faq.dd concepts.dd d-floating-point.dd migrate-to-shared.dd \
D1toD2.dd pdf-intro-cover.dd pdf-spec-cover.dd pdf-tools-cover.dd \
intro-to-datetime.dd simd.dd
intro-to-datetime.dd simd.dd deprecate.dd

SPECSRC=spec.dd lex.dd module.dd declaration.dd type.dd property.dd \
attribute.dd pragma.dd expression.dd statement.dd arrays.dd \
Expand Down Expand Up @@ -52,7 +52,7 @@ TARGETS=cpptod.html ctod.html pretod.html cppdbc.html index.html \
d-floating-point.html migrate-to-shared.html D1toD2.html \
unittest.html hash-map.html pdf-intro-cover.html \
pdf-spec-cover.html pdf-tools-cover.html intro-to-datetime.html \
simd.html
simd.html deprecate.html


PDFINTRO=index.html overview.html wc.html warnings.html builtin.html \
Expand Down Expand Up @@ -159,6 +159,8 @@ ddoc.html : $(DDOC) ddoc.dd

declaration.html : $(DDOC) declaration.dd

deprecate.html : $(DDOC) deprecate.dd

dll.html : $(DDOC) dll.dd

dstyle.html : $(DDOC) dstyle.dd
Expand Down