www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - const a storage class or a type modifier?

reply Jens Mueller <jens.k.mueller gmx.de> writes:
Hi,

I'm converting a .h to a d module. I'm following the guide on
http://www.digitalmars.com/d/2.0/htomodule.html
It says
"D has const as a storage class, not a type modifier. Hence, just drop
any const used as a type modifier"

I do not understand the first sentence nor do I find dropping the const
right. Why should I drop a const?
In TDPL const/immutable are type qualifiers. Type qualifier is a
synonym for type modifier, isn't it? And I know storage classes like
static/ref. In C you have the type qualifiers const, volatile, and
restrict and the storage classes auto, register, static, extern. Now
const in D is a storage class?

Jens
Nov 25 2010
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
Jens Mueller wrote:
 I'm converting a .h to a d module. I'm following the guide on
 http://www.digitalmars.com/d/2.0/htomodule.html
 It says
 "D has const as a storage class, not a type modifier. Hence, just drop
 any const used as a type modifier"
 
 I do not understand the first sentence nor do I find dropping the const
 right. Why should I drop a const?
 In TDPL const/immutable are type qualifiers. Type qualifier is a
 synonym for type modifier, isn't it? And I know storage classes like
 static/ref. In C you have the type qualifiers const, volatile, and
 restrict and the storage classes auto, register, static, extern. Now
 const in D is a storage class?

const in D1 is a storage class, in D2 it's a type modifier. The web page needs updating.
Nov 25 2010
parent Don <nospam nospam.com> writes:
Jens Mueller wrote:
 Walter Bright wrote:
 Jens Mueller wrote:
 I'm converting a .h to a d module. I'm following the guide on
 http://www.digitalmars.com/d/2.0/htomodule.html
 It says
 "D has const as a storage class, not a type modifier. Hence, just drop
 any const used as a type modifier"

 I do not understand the first sentence nor do I find dropping the const
 right. Why should I drop a const?
 In TDPL const/immutable are type qualifiers. Type qualifier is a
 synonym for type modifier, isn't it? And I know storage classes like
 static/ref. In C you have the type qualifiers const, volatile, and
 restrict and the storage classes auto, register, static, extern. Now
 const in D is a storage class?

page needs updating.

I'm attaching an svn diff. Can you apply it? Since one doesn't need to care about const then maybe one should drop the complete section. What do you think? I find this converting tutorial quite useful. Is there anything else missing or wrong? I'd like to adjust it because it helps people to add C libraries to D. Jens

I removed the section entirely for D2. It remains unaltered for D1. http://www.dsource.org/projects/phobos/changeset/2201
Nov 26 2010
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Walter Bright wrote:
 Jens Mueller wrote:
I'm converting a .h to a d module. I'm following the guide on
http://www.digitalmars.com/d/2.0/htomodule.html
It says
"D has const as a storage class, not a type modifier. Hence, just drop
any const used as a type modifier"

I do not understand the first sentence nor do I find dropping the const
right. Why should I drop a const?
In TDPL const/immutable are type qualifiers. Type qualifier is a
synonym for type modifier, isn't it? And I know storage classes like
static/ref. In C you have the type qualifiers const, volatile, and
restrict and the storage classes auto, register, static, extern. Now
const in D is a storage class?

const in D1 is a storage class, in D2 it's a type modifier. The web page needs updating.

I'm attaching an svn diff. Can you apply it? Since one doesn't need to care about const then maybe one should drop the complete section. What do you think? I find this converting tutorial quite useful. Is there anything else missing or wrong? I'd like to adjust it because it helps people to add C libraries to D. Jens
Nov 26 2010
prev sibling next sibling parent reply Trass3r <un known.com> writes:
 In TDPL const/immutable are type qualifiers. Type qualifier is a
 synonym for type modifier, isn't it? And I know storage classes like
 static/ref. In C you have the type qualifiers const, volatile, and
 restrict and the storage classes auto, register, static, extern. Now
 const in D is a storage class?

I also think const char* x in D2 is equal to const(char*) x while a direct translation would be const(char)* x So you might use the former version to keep compatibility with D1.
Nov 26 2010
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2010-11-26 07:51:20 -0500, Jens Mueller <jens.k.mueller gmx.de> said:

 Trass3r wrote:
 In TDPL const/immutable are type qualifiers. Type qualifier is a
 synonym for type modifier, isn't it? And I know storage classes like
 static/ref. In C you have the type qualifiers const, volatile, and
 restrict and the storage classes auto, register, static, extern. Now
 const in D is a storage class?

I also think const char* x in D2 is equal to const(char*) x while a direct translation would be const(char)* x So you might use the former version to keep compatibility with D1.

Haven't thought about that. Right. In D2 const T* is equal to const(T*). Let's check all the possible cases: void foo(const int *non_const_ptr_to_const, char *const const_ptr_to_non_const, const float *const const_ptr_to_const); In D2 you cannot express char *const. That's due to the transitivity of const. You can only do a const char* which is a constant pointer to constant. That's why I think foo should become in D2 void foo(const int*, char *, const(float*)); What do you think?

const(float*) or const(float)* are pretty much equivalent as a function parameter type. That's because the pointer is being passed to the function by copy. So whether it is const or not only matter when you are writing the function's body (can't mutate the local variable). It doesn't change anything for the caller. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Nov 26 2010
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2010-11-26 09:12:53 -0500, Jens Mueller <jens.k.mueller gmx.de> said:

 So how do you like it to be?
 void foo(const(int)*, char *, const(float)*);
 or
 void foo(const int*, char *, const float*);
 
 I still like the fixed original one namely
 void foo(const(int)*, char *, const float*);

I don't really have a preference. Note that for function arguments, you can also use 'in' to mean const: void foo(in int*, char *, in float*); My opinion is that we have too much choice. When everyone can write the same thing differently it can easily become confusing. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Nov 26 2010
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Trass3r wrote:
In TDPL const/immutable are type qualifiers. Type qualifier is a
synonym for type modifier, isn't it? And I know storage classes like
static/ref. In C you have the type qualifiers const, volatile, and
restrict and the storage classes auto, register, static, extern. Now
const in D is a storage class?

I also think const char* x in D2 is equal to const(char*) x while a direct translation would be const(char)* x So you might use the former version to keep compatibility with D1.

Haven't thought about that. Right. In D2 const T* is equal to const(T*). Let's check all the possible cases: void foo(const int *non_const_ptr_to_const, char *const const_ptr_to_non_const, const float *const const_ptr_to_const); In D2 you cannot express char *const. That's due to the transitivity of const. You can only do a const char* which is a constant pointer to constant. That's why I think foo should become in D2 void foo(const int*, char *, const(float*)); What do you think? I do not know much about D1. Is const transitive in D1? I think the page http://www.digitalmars.com/d/2.0/const3.html should not talk about storage class in regard to const and immutable. Jens
Nov 26 2010
prev sibling next sibling parent Trass3r <un known.com> writes:
 Let's check all the possible cases:
 void foo(const int *non_const_ptr_to_const,
          char *const const_ptr_to_non_const,
          const float *const const_ptr_to_const);

 In D2 you cannot express char *const. That's due to the transitivity of
 const. You can only do a const char* which is a constant pointer to
 constant.
 That's why I think foo should become in D2
 void foo(const int*, char *, const(float*));

Don't you mean foo(const(int)*, char*, const float*)?
Nov 26 2010
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Trass3r wrote:
Let's check all the possible cases:
void foo(const int *non_const_ptr_to_const,
         char *const const_ptr_to_non_const,
         const float *const const_ptr_to_const);

In D2 you cannot express char *const. That's due to the transitivity of
const. You can only do a const char* which is a constant pointer to
constant.
That's why I think foo should become in D2
void foo(const int*, char *, const(float*));

Don't you mean foo(const(int)*, char*, const float*)?

Right. Found this out myself a minute ago. Thanks. And as you say const float* is equivalent to const(float*). You're right const float* is better than const(float*). Jens
Nov 26 2010
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Michel Fortin wrote:
 On 2010-11-26 07:51:20 -0500, Jens Mueller <jens.k.mueller gmx.de> said:
 
Trass3r wrote:
In TDPL const/immutable are type qualifiers. Type qualifier is a
synonym for type modifier, isn't it? And I know storage classes like
static/ref. In C you have the type qualifiers const, volatile, and
restrict and the storage classes auto, register, static, extern. Now
const in D is a storage class?

I also think const char* x in D2 is equal to const(char*) x while a direct translation would be const(char)* x So you might use the former version to keep compatibility with D1.

Haven't thought about that. Right. In D2 const T* is equal to const(T*). Let's check all the possible cases: void foo(const int *non_const_ptr_to_const, char *const const_ptr_to_non_const, const float *const const_ptr_to_const); In D2 you cannot express char *const. That's due to the transitivity of const. You can only do a const char* which is a constant pointer to constant. That's why I think foo should become in D2 void foo(const int*, char *, const(float*)); What do you think?

const(float*) or const(float)* are pretty much equivalent as a function parameter type. That's because the pointer is being passed to the function by copy. So whether it is const or not only matter when you are writing the function's body (can't mutate the local variable). It doesn't change anything for the caller.

That's true. So how do you like it to be? void foo(const(int)*, char *, const(float)*); or void foo(const int*, char *, const float*); I still like the fixed original one namely void foo(const(int)*, char *, const float*); Because it's the most explicit one and one should know the difference. Even though one is not implementing the function. But the signature tells you something. If you do const float* it tells you that the implementation isn't changing its copied pointer. If you do const(float)* then it may change its copied value of the pointer. But I agree it's rather artificial because it's a copy anyway. But I like it to be explicit. In general I prefer the const() notation more than the one without round brackets when dealing with types. Jens
Nov 26 2010
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Michel Fortin wrote:
 On 2010-11-26 09:12:53 -0500, Jens Mueller <jens.k.mueller gmx.de> said:
 
So how do you like it to be?
void foo(const(int)*, char *, const(float)*);
or
void foo(const int*, char *, const float*);

I still like the fixed original one namely
void foo(const(int)*, char *, const float*);

I don't really have a preference. Note that for function arguments, you can also use 'in' to mean const: void foo(in int*, char *, in float*); My opinion is that we have too much choice. When everyone can write the same thing differently it can easily become confusing.

Right. Definitely too much choice. So it becomes a matter of style and I think the documentation should be in one consistent style. For interfacing with C I prefer the const version over in. Because I consider in and out to be like one pair of shoes. And since out doesn't make sense when interfacing with C I don't like it. But for non interfacing code one should use in/out because they are more explicit than const. Jens
Nov 26 2010
prev sibling next sibling parent Trass3r <un known.com> writes:
 I don't really have a preference. Note that for function arguments, you  
 can also use 'in' to mean const:

 	void foo(in int*, char *, in float*);

Isn't "in" the default (even if nothing is specified)?
Nov 26 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday 26 November 2010 10:24:02 Trass3r wrote:
 I don't really have a preference. Note that for function arguments, you
 
 can also use 'in' to mean const:
 	void foo(in int*, char *, in float*);

Isn't "in" the default (even if nothing is specified)?

No. in is the same as const scope. If in were the default, all function parameters would have to be const or immutable (since you couldn't ever unmark them as const - though marking them as immutable would override const). - Jonathan M Davis
Nov 26 2010
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Trass3r wrote:
I don't really have a preference. Note that for function
arguments, you can also use 'in' to mean const:

	void foo(in int*, char *, in float*);

Isn't "in" the default (even if nothing is specified)?

I don't know. I never read this. I don't think that's the case. For example void foo(in int a) { //a = 1; // won't compile } Whereas void foo(int a) { a = 1; // this compiles } compiles. So in is definitely not the default. Jens
Nov 27 2010
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Don wrote:
 Jens Mueller wrote:
Walter Bright wrote:
const in D1 is a storage class, in D2 it's a type modifier. The web
page needs updating.

I'm attaching an svn diff. Can you apply it? Since one doesn't need to care about const then maybe one should drop the complete section. What do you think? I find this converting tutorial quite useful. Is there anything else missing or wrong? I'd like to adjust it because it helps people to add C libraries to D. Jens

I removed the section entirely for D2. It remains unaltered for D1. http://www.dsource.org/projects/phobos/changeset/2201

Removing it leaves some questions open. At least the current thread revealed some problems. What about the attached update? Jens
Nov 28 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
AFAIK "in" will guarantee you can't change a variable, even when using
arrays, e.g.:

void foo(in int[] a) {
   int[] b;
   a[0] = 1; // won't compile
   a = b;     // won't compile (I think?)
}

void foo(int[] a) {
   int[] b;
   a[0] = 1; // compiles, and changes are reflected in the caller
   a = b;     // compiles, but it doesn't change "a" in the calling code
}

I don't have DMD on this PC so I haven't tested it.

On 11/28/10, Jens Mueller <jens.k.mueller gmx.de> wrote:
 Don wrote:
 Jens Mueller wrote:
Walter Bright wrote:
const in D1 is a storage class, in D2 it's a type modifier. The web
page needs updating.

I'm attaching an svn diff. Can you apply it? Since one doesn't need to care about const then maybe one should drop the complete section. What do you think? I find this converting tutorial quite useful. Is there anything else missing or wrong? I'd like to adjust it because it helps people to add C libraries to D. Jens

I removed the section entirely for D2. It remains unaltered for D1. http://www.dsource.org/projects/phobos/changeset/2201

Removing it leaves some questions open. At least the current thread revealed some problems. What about the attached update? Jens

Nov 28 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday 28 November 2010 05:28:45 Andrej Mitrovic wrote:
 AFAIK "in" will guarantee you can't change a variable, even when using
 arrays, e.g.:
 
 void foo(in int[] a) {
    int[] b;
    a[0] = 1; // won't compile
    a = b;     // won't compile (I think?)
 }
 
 void foo(int[] a) {
    int[] b;
    a[0] = 1; // compiles, and changes are reflected in the caller
    a = b;     // compiles, but it doesn't change "a" in the calling code
 }
 
 I don't have DMD on this PC so I haven't tested it.

Well, in is essentially an alias for const scope, so no, you can't change any variables marked in. And since const is transitive, that includes anything that the variable references. So, arrays marked with in are fully const and cannot be altered in any way. - Jonathan M Davis
Nov 28 2010
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I think scope needs to be documented better in the docs. I didn't even
know it could be used in the parameter list, or what it does for that
matter.

On 11/28/10, Jonathan M Davis <jmdavisProg gmx.com> wrote:
 On Sunday 28 November 2010 05:28:45 Andrej Mitrovic wrote:
 AFAIK "in" will guarantee you can't change a variable, even when using
 arrays, e.g.:

 void foo(in int[] a) {
    int[] b;
    a[0] = 1; // won't compile
    a = b;     // won't compile (I think?)
 }

 void foo(int[] a) {
    int[] b;
    a[0] = 1; // compiles, and changes are reflected in the caller
    a = b;     // compiles, but it doesn't change "a" in the calling code
 }

 I don't have DMD on this PC so I haven't tested it.

Well, in is essentially an alias for const scope, so no, you can't change any variables marked in. And since const is transitive, that includes anything that the variable references. So, arrays marked with in are fully const and cannot be altered in any way. - Jonathan M Davis

Nov 28 2010
parent lurker <lurk lurking.net> writes:
Andrej Mitrovic Wrote:

 I think scope needs to be documented better in the docs. I didn't even
 know it could be used in the parameter list, or what it does for that
 matter.

One of D's strong points is that you never can know what amazing things it can do. Bearophile always complains that D doesn't do 'Foo' or 'Bar', but these undocumented features since year 200x always bring a smile to my lips. You can say 'haha' in the voice of that simpsons wiggum son character.
Nov 28 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
D's slogan should be "There's a keyword for that." :p

On 11/28/10, lurker <lurk lurking.net> wrote:
 Andrej Mitrovic Wrote:

 I think scope needs to be documented better in the docs. I didn't even
 know it could be used in the parameter list, or what it does for that
 matter.

One of D's strong points is that you never can know what amazing things it can do. Bearophile always complains that D doesn't do 'Foo' or 'Bar', but these undocumented features since year 200x always bring a smile to my lips. You can say 'haha' in the voice of that simpsons wiggum son character.

Nov 28 2010
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On Sun, 28 Nov 2010 15:13:23 +0000
Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:

 D's slogan should be "There's a keyword for that." :p

That has been my impression in first few weeks playing with D Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 28 2010
prev sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:

 D's slogan should be "There's a keyword for that." :p

And here I thought we only needed 'static'... -- Simen
Nov 29 2010