Deprecated Features - D Programming Language 2.0 - Digital Mars
Description: D Programming Language
Keywords: D programming language

D Programming Language 2.0

- Forum
- Wiki
- Search
- Downloads
- Home

Last update Fri Feb 10 01:37:17 2012

# Deprecated Features

Sometimes it becomes clear that a feature is just a bad idea. These are called deprecated features and once they are judged to merit removal from the language, they follow a procedure in order to allow plenty of time for users to adjust to the change.

Deprecated Features
Feature | Spec | Warn | Dep | Error | Gone
--- | --- | --- | --- | --- | ---
Base Class Protection | 2.058 | N/A | 2.058 |  |
Using length in index expressions | ? | N/A | 2.041 |  |
typedef | 2.057 | N/A | 2.057 |  |
Variable shadowing inside functions | ? | N/A | 0.161 |  |
invariant as an alias for immutable | 2.057 | N/A | 2.057 |  |
Using * to dereference arrays | ? | N/A | 2.057 |  |
Removing an item from an associative array with delete | ? | N/A | 0.127 |  |
.offset property | ? | N/A | 0.107 |  |
.size property | ? | N/A | 0.107 | 0.107 |
Escape string literals | ? | N/A | 2.026 |  |
Lower case 'l' suffix for integer literals | ? | N/A | 1.054 | 0.174 |
Octal literals | 2.054 | N/A | 2.053 |  |
Upper case 'I' suffix for imaginary literals | ? | N/A | 0.154 |  |
HTML source files | ? | N/A | 2.013 |  |
.typeinfo property | ? | N/A | 0.093 |  |
C-style function pointers | ? | N/A | 2.050 |  |
C-style array pointers | ? | N/A | 2.050 |  |
if (v; e) | ? | N/A | 0.149 | 0.174 |
volatile | 2.013 | N/A | 2.013 |  |
Non-final switch statements without a default case | 2.054 | N/A | 2.054 |  |
Hiding base class functions | 2.054 | N/A | 2.054 |  |
.min property for floating point types | future |  |  |  |
imaginary and complex types | future |  |  |  |
floating point NCEG operators | future |  |  |  |
.sort and .reverse properties for arrays | future |  |  |  |
delete | future |  |  |  |
overriding without override | future |  |  |  |

Spec
  Removal from the Specification
Warn
  The compiler emits a warning if the feature is used
Dep
  The compiler issues an error if not compiled with the -d switch
Error
  It is an error to use the feature
Gone
  The feature is completely gone

### Base Class Protection

Base class protections are things like:

    class A : protected B {
       ...
    }

#### Corrective Action

Delete the protection attribute keyword from in front of the base class and base interfaces.

#### Rationale

With D's module system, it doesn't seem to serve any useful purpose, and has never worked correctly.

### Using length in index expressions

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];

#### Corrective Action

Replace length with the equivalent '$'

#### Rationale

The implicitly defined length variable shadows existing declarations, and is less concise than the alternative.

### typedef

typedef can be used to construct a strongly-typed alias of a type.

    typedef int myint;
    static assert(!is(myint == int));

#### Corrective Action

Replace use of typedef with alias.

#### Rationale

typedef is not flexible enough to cover all use cases. This is better done with a library solution.

### Variable shadowing inside functions

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?
        }
    }

#### Corrective Action

Rename shadowing variables so they don't conflict.

#### Rationale

Variable shadowing can introduce hard to find bugs where the wrong variable is modified.

### invariant as an alias for immutable

The invariant storage class and type modifier is an alias for immutable.

    static assert(is(invariant(int) == immutable(int)));

#### Corrective Action

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.

#### Rationale

The alias is unnecessary.

### Using * to dereference arrays

D array variables can be dereferenced to get the first element, much like pointers.

    int[] arr = [1, 2, 3];
    assert(*arr == 1);

#### Corrective Action

Use indexing syntax to access first member.

    int[] arr = [1, 2, 3];
    assert(arr[0] == 1);

#### Rationale

D arrays are not pointers.

### Removing an item from an associative array with delete

delete can be used to remove an item from an associative array.

    int[int] aa = [1 : 2];
    delete aa[1];
    assert(1 !in aa);

#### Corrective Action

Use .remove instead.

    int[int] aa = [1 : 2];
    aa.remove(1);
    assert(1 !in aa);

#### Rationale

The delete syntax is confusing and conflicts with the normal delete syntax.

### .offset property

The .offset property can be used to get member offset information.

    struct S { int a, b; }
    static assert(S.b.offset == 4);

#### Corrective Action

Use .offsetof instead

    struct S { int a, b; }
    static assert(S.b.offsetof == 4);

#### Rationale

The .offset syntax has been superseded by .offsetof

### .size property

The .size property can be used to get type size information

    struct S { int a, b; }
    static assert(S.size == 8);

#### Corrective Action

Use .sizeof instead

    struct S { int a, b; }
    static assert(S.sizeof == 8);

#### Rationale

The .size syntax has been superseded by .sizeof

### Escape string literals

Escape string literals can be used to describe characters using escape sequences.

    string x = "hello" ~ \n;

#### Corrective Action

Put escape sequences inside a regular string literal.

    string x = "hello\n";

#### Rationale

Escape string literals are unintuitive and unnecessary.

### Lower case 'l' suffix for integer literals

Lower case 'l' is an alternative suffix to denote 64 bit integer literals.

    auto x = 123l;

#### Corrective Action

Use the upper case 'L' suffix.

    auto x = 123L;

#### Rationale

The lower case suffix is easily confused with the digit '1'.

### Octal literals

Octal literals can be used to enter literals in base 8.

    auto x = 0123;

#### Corrective Action

Use the octal!num template.

    auto x = octal!123;

#### Rationale

The use of a leading zero is confusing, as 0123 != 123.

### Upper case 'I' suffix for imaginary literals

The 'I' suffix can be used to denote imaginary floating point values.

    auto x = 1.234I;

#### Corrective Action

Use the lower case 'i' suffix.

    auto x = 1.234i;

#### Rationale

The 'I' suffix is easily confused with the digit '1'.

### HTML source files

The D compiler can parse html files by ignoring everything not contained in <code></code> tags.

    <html>
    <code>
        ... source ...
    </code>
    </html>

#### Corrective Action

Extract code to regular source files.

#### Rationale

This has been replaced for documentation by the introduction of ddoc

### HTML source files

The D compiler can parse html files by ignoring everything not contained in <code></code> tags.

    <html>
    <code>
        ... source ...
    </code>
    </html>

#### Corrective Action

Extract code to regular source files.

#### Rationale

This has been replaced for documentation by the introduction of ddoc

### .typeinfo property

The .typeinfo property can be used to get the associated TypeInfo class.

    T.typeinfo

#### Corrective Action

Use typeid() instead

    typeid(T)

#### Rationale

The .typeinfo syntax has been superseded by typeid()

### C-style function pointers

C-style function pointers can be used in D.

    alias void(*fptr)(int, long);

#### Corrective Action

Replace with D-style function pointers.

    alias void function(int, long) fptr;

#### Rationale

The D syntax is much cleaner and easier to use.

### C-style array pointers

C-style array pointers can be used in D.

    alias float *arrayptr[10][15];

#### Corrective Action

Replace with D-style array pointers.

    alias float[15][10]* arrayptr;

#### Rationale

The D syntax is much cleaner and easier to use.

### if (v; e)

This syntax can be used to declare a variable in an if statement condition.

    if (v; calculateAndReturnPointer()) { ... }

#### Corrective Action

Replace with an auto declaration.

    if (auto v = calculateAndReturnPointer()) { ... }

#### Rationale

The syntax is clearer with auto.

### volatile

volatile can be used to mark statement, in order to prevent some compiler optimizations.

    volatile
    {
        ... do something involving ghared variables ...
    }

#### Corrective Action

Convert the code to use synchronized statements instead.

#### Rationale

volatile statements are a misfeature.

### Non-final switch statements without a default case

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();
    }

#### Corrective Action

Add the default case manually.

    switch(a)
    {
    case 1:
        break;
    case 2:
        break;
    default:
        assert(0);
    }

#### Rationale

Missing default cases can hide bugs, and making the default case explicit should be mandatory.

### Hiding base class functions

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) {}
    }

#### Corrective Action

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
    }

#### Rationale

This is an error that is already detected at runtime, and is being extended to compile time.

### .min property for floating point types

Floating point types have the .min property to access the smallest value.

    enum m = real.min;

#### Corrective Action

Replace with .min_normal

    enum m = real.min_normal;

#### Rationale

The name min_normal is more accurate, as .min does not include denormalized floating point values.

### imaginary and complex types

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);

#### Corrective Action

Use the library types in std.complex

#### Rationale

These types are too specialized to be a part of the core lanugage.

### floating point NCEG operators

D currently the NCEG floating point operators (!<>=, <>, <>=, !>, !>=, !<, !<=, !<>) for comparisons involving NaNs.

#### Corrective Action

Use the normal operators and std.math.isNaN.

#### Rationale

These operators are too specialized to be a part of the core lanugage.

### .sort and .reverse properties for arrays

D arrays can be manipulated using these built-in properties.

    int[] x = [2, 3, 1];
    assert(x.sort == [1, 2, 3]);

#### Corrective Action

Use the generic functions in std.algorithm

#### Rationale

These operations are better implemented in the standard library

### delete

Memory allocated on the GC heap can be freed with delete.

    auto a = new Class();
    delete a;

#### Corrective Action

Use object.clear() instead.

    auto a = new Class();
    clear(a);

#### Rationale

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.

### overriding without override

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() {}
    }

#### Corrective Action

Mark overriding functions with 'override'

    class A
    {
        void fun() {}
    }
    class B : A
    {
        override void fun() {}
    }

#### Rationale

Making the 'override' attribute mandatory makes it explicit, and can catch errors when a base class function is accidentally overridden.

Forums | Comments | D | Search | Downloads | Home
Copyright © 1999-2012 by Digital Mars ®, All Rights Reserved | Page generated by Ddoc.