Meaning of const

Timon Gehr timon.gehr at
Wed Jan 25 14:50:57 PST 2012

On 01/25/2012 02:29 AM, H. S. Teoh wrote:
> On Tue, Jan 24, 2012 at 08:01:41PM -0500, bearophile wrote:
>> Jonathan M Davis:
>>> Now, the confusing part is the fact that unlike C++, D allows you to put the
>>> const for making the function on the _left-hand_ side of the function (C++
>>> only lets you put it on the right). This is to increase consistency between
>>> modifers (public, override, pure, etc.) - they _all_ can go on both the right
>>> and left (which is very unfortunate in the case of const and immutable IMHO).
>>> That means that const (and immutable) always modify the function rather than
>>> the return value unless you use parens.
>> Some time ago we have discussed this topic in an enhancement request in Bugzilla. The idea was to disallow code like:
>> struct Foo {
>>      int x;
>>      const const(int) bar() {
>>          return 0;
>>      }
>> }
>> void main() {}
>> and require the struct "const", "immutable" to be only on the right if present.
>> Walter shot this idea down for consistency. But I generally don't want
>> consistency when it's just a potential source of confusion for the
>> programmer :-)
> [...]
> How can this be consistency? For example:
> 	class A {
> 		const int x;
> 		@property const int y();
> 	}
> Now you have typeof(A.x)==const(int) and typeof(A.y)==int. Seems quite
> inconsistent to me.
> But since Walter doesn't like the idea of restricting the syntax to 'int
> y() const', then what about making it mandatory to write:
> 	const(int) x;
> instead of:
> 	const int x;
> ?

You essentially propose to remove the const/immutable/shared/inout 
storage classes for variables. It would break almost every D program and 
I don't see many benefits.
> Requiring the parentheses is a bit extreme, I admit, but it touches upon
> another area of D syntax that I don't quite like, and that is const or
> immutable applied to arrays:
> 	const(int)[] x;		// array of const(int)
> 	const(int[]) x;		// const array of int
> 	const int[] x;		// ??? const array of const int? Or one
> 				// of the above?


The storage class of a declaration applies to the whole declaration.
> It gets worse when you throw in ref:

Ref does not change anything but the calling convention *of the 
function*. The reference itself cannot be rebound, there is no syntax 
for it.

> 	ref int f();		// returns int* (I think?)
> 	ref const(int) f();	// returns const(int)* (?)
> 	ref const int f();	// ???
> 	const ref int f():	// ???
> The last line is quite bad. Is the return type const(int*) or
> const(int)*, or is it just int* (i.e., const applies to f not the return
> value)?

It is int.

> 	ref const(int)[] x;	// ref to array of const(int)?

Note that ref can only be on a function or on a parameter.

> 	const(ref int)[] x;	// array of refs to int?

No such thing exists.

> 	const ref int[] x;	// array of ???

const(int[]). Declaration is invalid, would have to be a parameter.

> 	const ref int[] x();	// const function that returns ref int[]?

It returns int[], by reference. It is equivalent to

int[] x()const ref;

Though most people will prefer to have 'ref' on the lhs:

ref int[] x()const;

It still applies to the function though.

> 	const const ref int[] x();	// const function returning what?

Redundant storage class const.

ref int[] x()const const; is the same thing.

> The more I think about this, the more confusing it becomes.

It is very simple. What may be confusing you is that 
const/immutable/shared/inout are both type constructors and storage classes.

> If
> parentheses were mandatory after const, things would be much, much
> better:
> 	const(ref int) x;
> 	const(ref const(int)) x;
> 	... etc.
> Much clearer to me.

It is not to me. This is not valid syntax. Also, types of the general 
form const(...const(...)...) don't make a lot of sense. Const is transitive.

More information about the Digitalmars-d-learn mailing list