www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - const and immutable

reply Tim Verweij <tjverweij gmail.com> writes:
Hey all,

I'm having some trouble understanding the whole const and immutable of D2,
especially since it seems documentation is not consistent (Or I'm missing some
things). I write quite a lot of C++ code btw, so I'm familiar with that.

---

http://www.digitalmars.com/d/2.0/htomodule.html says: D has const as a storage
class, not a type modifier. Hence, just drop any const used as a type modifier:
  void foo(const int *p, char *const q);
becomes:
  void foo(int* p, char* q);

http://www.digitalmars.com/d/2.0/const3.html includes D examples like:
  void foo(const int* x, int* y)

Is the information on the first page not updated for D2?

---

Is the following correct? (this confuses me)

  immutable int somefunc();
means the same thing as
  int somefunc() immutable;
and not the same thing as
  immutable(int) somefunc();
even though the first syntax looks very much like this:
  immutable int x;

---

I think I understand the difference between const and immuable when
considering references and pointers, but how exactly is const different from
immutable in:
const int x; versus immutable int x;
void somefunc(const int x); versus void somefunc(immutable int x);
const(int) somefunc(); versus immutable(int) somefunc();

How does this system interact with in/out/ref etc? Can I for example have
"const ref int somefunc()"?

---

Tim
Jul 06 2010
next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Tim Verweij <tjverweij gmail.com> wrote:

 http://www.digitalmars.com/d/2.0/const3.html includes D examples like:
   void foo(const int* x, int* y)

 Is the information on the first page not updated for D2?

That seems correct.
 Is the following correct? (this confuses me)

   immutable int somefunc();
 means the same thing as
   int somefunc() immutable;
 and not the same thing as
   immutable(int) somefunc();
 even though the first syntax looks very much like this:
   immutable int x;

Yes. immutable always applies to the whole type, which in the function case would be int function().
 I think I understand the difference between const and immuable when
 considering references and pointers, but how exactly is const different  
 from
 immutable in:
 const int x; versus immutable int x;
 void somefunc(const int x); versus void somefunc(immutable int x);
 const(int) somefunc(); versus immutable(int) somefunc();

It isn't. For non-reference types, immutable and const are indistinguishable.
 How does this system interact with in/out/ref etc? Can I for example have
 "const ref int somefunc()"?

Absolutely. -- Simen
Jul 06 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 06 Jul 2010 10:56:11 -0400, Tim Verweij <tjverweij gmail.com>  
wrote:

 Hey all,

 I'm having some trouble understanding the whole const and immutable of  
 D2,
 especially since it seems documentation is not consistent (Or I'm  
 missing some
 things). I write quite a lot of C++ code btw, so I'm familiar with that.

 ---

 http://www.digitalmars.com/d/2.0/htomodule.html says: D has const as a  
 storage
 class, not a type modifier. Hence, just drop any const used as a type  
 modifier:
   void foo(const int *p, char *const q);
 becomes:
   void foo(int* p, char* q);

 http://www.digitalmars.com/d/2.0/const3.html includes D examples like:
   void foo(const int* x, int* y)

 Is the information on the first page not updated for D2?

Yes, the first page is not routinely updated, it looks very outdated. consider it a bug of the documentation. D1 has no const type modifier, D2 does.
 ---

 Is the following correct? (this confuses me)

   immutable int somefunc();
 means the same thing as
   int somefunc() immutable;
 and not the same thing as
   immutable(int) somefunc();
 even though the first syntax looks very much like this:
   immutable int x;

This is a large part of confusion to many users. It's done this way for consistency. For example, a synchronized method looks like this: synchronized int foo(); Which does not return a synchronized int, but rather means the function is synchronized on this. In addition, many attributes can be applied in groups via: attribute { .... } or attribute: .... Similar to protection. The same goes for const. So this: const int somefunc(); and const { int somefunc(); } are supposed to be equivalent. People on this NG have petitioned without success to get Walter to remove that syntax, or make it mean what it looks like it means. Code like this: immutable immutable(int)* foo(); should not be required/allowed :)
 ---

 I think I understand the difference between const and immuable when
 considering references and pointers, but how exactly is const different  
 from
 immutable in:
 const int x; versus immutable int x;

Functionally, no difference. Once declared, those cannot be changed. However, semantically, there is a difference when taking the address: immutable int x; const int y; immutable(int)* yp = &y; // does not compile! const(int)*xp = &x; // ok, immutable implicitly converts to const. The thing to remember is that const means you cannot change that value through that pointer. But there is no guarantee that something else is able to change the value. If declaring x to be not changing, the best way to do it is declare it immutable, because that is what it is. Declaring it const means you are saying something else might be able to change the value.
 void somefunc(const int x); versus void somefunc(immutable int x);
 const(int) somefunc(); versus immutable(int) somefunc();

These are the same as above. Note that D enforces transitive const/immutability. But it also allows implicit conversions to any constancy with value types (types without any references in them) because simply copying the data completely decouples it from the original. So things like this are possible: const int x = 5; int y = x; // ok to copy const to mutable for value types. But this is not: int *xp = &x; // error, because there is a reference here!
 How does this system interact with in/out/ref etc? Can I for example have
 "const ref int somefunc()"?

Yes. in/out/ref are all storage classes and can be applied to any type. However, you can only use in and out on function parameters, and you can only apply ref to function parameters and return values. You can't declare a reference as a local variable like you can in C++. There is also a type modifier called inout, which is somewhat confusing at first but aids greatly in reducing source and gerenated code. However, it is currently very broken. Eventually, most functions will be inout. -Steve
Jul 06 2010
prev sibling next sibling parent reply BCS <none anon.com> writes:
Hello Tim,

 
 I think I understand the difference between const and immuable when
 considering references and pointers, but how exactly is const
 different from immutable in:

 const(int) somefunc(); versus immutable(int) somefunc();

BTW both of those are pointless. The following works: import std.stdio; const(int) Fn(){return 0;} void main() { int i = Fn(); i = 5; writef("%d\n", i); } -- ... <IXOYE><
Jul 06 2010
next sibling parent Tim Verweij <tjverweij gmail.com> writes:
Thanks for all replies, that was very helpful. I have one more question about
inout. If I understand correctly, it is always coupled to the use of a parameter
and cannot be used to get rid of the double GetBar in the following C++ example:

class Foo
{
public:
  const Bar& GetBar() { return bar; } const
        Bar& GetBar() { return bar; }
private:
  Bar bar;
}

Is this correct? Thx for your replies.
Jul 06 2010
prev sibling parent reply Tim Verweij <tjverweij gmail.com> writes:
Not sure if I'm double posting now. Sorry if I am, but I didn't see my own post
appear this time.

Anyway, thanks for your replies, that was very helpful. I had one more question
about inout. If I understand correctly it cannot be used to get rid of the
double
GetBar function in the following C++ example:

class Foo
{
public:
  const Bar& GetBar() { return mBar; } const
        Bar& GetBar() { return mBar; }
private:
  Bar mBar;
};

Is that correct? Or is there a way to make this one function in D?
Jul 06 2010
parent Tim Verweij <tjverweij gmail.com> writes:
== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s article
 I'm not positive, but I think the second const applies to the second
 function, I think you meant:
 const Bar& GetBar() const { return mBar; }

 And yes, inout will reduce this to one function:
 ref inout(Bar) GetBar() inout { return mBar; }
 In addition, you do not have to specify the immutable version, therefore
 it actually saves 2 functions.
 That is why it's there :)

Schveighoffer)? I haven't had the time to try this yet. I have ordered Andrei Alexandrescu's book "The D Programming Language". Does it cover inout as well, or is this feature newer than the book?
Jul 06 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 06 Jul 2010 12:10:04 -0400, Tim Verweij <tjverweij gmail.com>  
wrote:

 Not sure if I'm double posting now. Sorry if I am, but I didn't see my  
 own post
 appear this time.

 Anyway, thanks for your replies, that was very helpful. I had one more  
 question
 about inout. If I understand correctly it cannot be used to get rid of  
 the double
 GetBar function in the following C++ example:

 class Foo
 {
 public:
   const Bar& GetBar() { return mBar; } const
         Bar& GetBar() { return mBar; }
 private:
   Bar mBar;
 };

 Is that correct? Or is there a way to make this one function in D?

I'm not positive, but I think the second const applies to the second function, I think you meant: const Bar& GetBar() const { return mBar; } And yes, inout will reduce this to one function: ref inout(Bar) GetBar() inout { return mBar; } In addition, you do not have to specify the immutable version, therefore it actually saves 2 functions. That is why it's there :) -Steve
Jul 06 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 06 Jul 2010 16:08:21 -0400, Tim Verweij <tjverweij gmail.com>  
wrote:

 == Quote from Steven Schveighoffer (schveiguy yahoo.com)'s article
 I'm not positive, but I think the second const applies to the second
 function, I think you meant:
 const Bar& GetBar() const { return mBar; }

mistake.
 And yes, inout will reduce this to one function:
 ref inout(Bar) GetBar() inout { return mBar; }
 In addition, you do not have to specify the immutable version, therefore
 it actually saves 2 functions.
 That is why it's there :)

Steven Schveighoffer)? I haven't had the time to try this yet.

Very broken. It works in a small subset of cases. Look for this bug to be closed when it's fixed (add yourself to the CC of the bug): http://d.puremagic.com/issues/show_bug.cgi?id=3748 Also, here is a complete overview of how it is supposed to work: http://prowiki.org/wiki4d/wiki.cgi?action=browse&;id=LanguageDevel/DIPs/DIP2&amp;oldid=DiP2
 I have ordered Andrei Alexandrescu's book "The D Programming Language".  
 Does it
 cover inout as well, or is this feature newer than the book?

It's in the book. I reviewed the book, but I don't have the final copy, so I'm not sure how much is discussed. I remember there were some omissions in the copy I reviewed. -Steve
Jul 06 2010