Interested in D, spec confuses me.

Jacob Carlborg via Digitalmars-d digitalmars-d at puremagic.com
Tue Feb 2 07:21:29 PST 2016


On 2016-02-02 15:36, Bambi wrote:

> 1. const isn't constant
>   To my mind, a const is a value that cannot change from the moment it
> is defined. But D allows for modification of const values through
> non-const references and pointers, and does not promise to optimize
> const by placing it in read only memory or similar. Instead, it provides
> immutable, which does promise an constant value throughout the lifetime
> of the value. I'm not sure why this distinction was created, or what
> const is supposed to accomplish here. It's just very confusing to have
> two keywords that intuitively do the same thing but don't really.
> Applying these keywords to methods would seem to make the data of the
> parent object immutable to only the function. Which might be useful but
> isn't immediately obvious from the written form.

"const" is like a read-only view of data.

int a = 3;
const(int*) b = &a;
assert(*b == 3);
a = 4;
assert(*b == 4);
*b = 5; // Error: cannot modify const expression *b

"const" also acts like a super set of immutable and mutable data:

const(int*) a = new int;
immutable(int)* b = new int;
int* c = new int;
foo(a);
foo(b);
foo(c);

void foo(const(int*) a) {}

That would mean that "foo" will not change "a" regardless of if the 
original data is immutable, const or mutable.

> The example snippet ' immutable(int[]) bar() immutable {} ' brings back
> bad memories of redundant declarations of the style ' Object object =
> new Object(); '. And homonyms in programming languages seem like a bad
> idea in general.

The first immutable means that "bar" returns an immutable array of ints. 
The second immutable means that "bar" cannot modify the "this" reference:

class Foo
{
     int a = 3;

     void bar() immutable
     {
         a = 4; // Error: cannot modify immutable expression this.a
     }
}

> 2. when is an extern an extern?
>   The wiki page on interfacing with C states that C globals require an
> extra extern. The extern definition in the spec clarifies that extern(C)
> alone will copy the global into the current module, but that extern
> extern(C) will read it right from the C code. Or maybe it means to say
> that using extern(C) alone will only specify a different calling
> convention for the variable you are declaring. It's honestly not clear.
> Homonym problem again.

"extern(C)" means C linkage and calling conventions. "extern" means that 
a symbol is defined in another object file.

extern (C) int foo;

Compiling that and running the "nm" command to print the symbols will 
list "foo":

00000000000000d0 S _foo

Adding "extern" and doing the same:

extern(C) extern int foo;

Will result in this output:

U _foo

That means "foo" is undefined. That is, the linker needs to find that 
symbol in some other library.

If you create bindings to a C library, you would use "extern(C) extern". 
If you create a library in D that some C code should access you would 
use "extern(C)".,

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list