Meaning of const

Jonathan M Davis jmdavisProg at gmx.com
Tue Jan 24 17:51:45 PST 2012


On Tuesday, January 24, 2012 16:55:16 H. S. Teoh wrote:
> On Tue, Jan 24, 2012 at 07:06:47PM -0500, Jonathan M Davis wrote:
> [...]
> 
> > So, while a C++ programmer expects that
> > 
> > int f2() const
> > 
> > means that f2 is const, they're likely to be surprised by the fact that
> > in
> > 
> > const int f1()
> > 
> > it's the int that's const, not f1.
> 
> [...]
> 
> Wait, I thought 'const int f1()' means that 'int f1(const this, ...)',
> not the other way round?

It does. I mis-typed. Sorry.

> I guess you're trying to say that in C++:
> 
> 	const int f();
> 
> means the return value is 'const int', but in D:
> 
> 	const int f();
> 
> means the same thing as 'int f() const', and the return value is 'int'.
> Is that correct?

Yes. In C++, const must go on the right if it's going to modify the function 
rather than the return type.

> //
> 
> Anyway, I find this variable syntax a bit annoying. The basic syntax of
> a function is:
> 
> 	<return type> <func_name>(<args...>) { <body> }
> 
> But now we have additional modifiers like 'pure', 'lazy', 'const', etc.,
> and syntax becomes:
> 
> 	<modifiers> <return type> <func_name>(<args...>) <more_modifiers> { <body>
> }
> 
> Which makes sense, since then you can write 'pure int f()' which reads
> nicely. However, in the case of const, it's very confusing because
> you're used to writing 'const <typename>' to mean 'const(<typename>)',
> yet here 'const int f()' means 'const(int f())' rather than 'const(int)
> f()':
> 
> 	class A {
> 		const int f();
> 	}
> 	auto a = new A;
> 	const int x;	// typeof(x) == const(int)
> 	auto y = a.f();	// typeof(y) == int
> 
> This is a visual ambiguity with the basic pattern '<return type>
> <func_name>(...)', which I find very jarring.
> 
> Should I file an issue for this? :)

There's nothing to file. It's been discussed before, and Walter shot down any 
changes. Attributes can go on either the right-hand side or the left-hand side 
of a function. In general, this is a complete non-issue. The problem is the 
ambiguity of

const int f()

where most people expect that to mean that the int is const, not the function. 
The proposed solution is to require that const be on the right (as in C++), 
but Walter insists on allowing const on the left for consistency's sake (since 
all of the other modifiers can go on both sides). immutable and shared have the 
same problem. But none of the other modifiers can apply to both variables and 
functions, so they aren't an issue.

Having attributes on both sides is an artifact of borrowing from both C++ and 
C#/Java. The only modifiers on functions which exists in C++ are static and 
const; static goes on the left (but it can't affect return types), and const is 
always on the right. C# and Java, on the other hand, put all of their modifiers 
on the left, and none of those modifiers can apply to return types (they don't 
have const). So, requiring that all of the modifiers go on the left would 
conflict with C++ (and cause the issue that we currently have with const), and 
requiring that they all go on the right would be too weird for the Java and C# 
folks. So, we ended up with both.

All in all, I don't think that it's an issue, except for const, immutable, and 
shared, in which case, it's a big issue, but Walter refuses to change it.

In general, I'd argue that it's best practice to always put const, shared, and 
immutable on the right-hand side of the function to avoid this problem. I 
would consider any function which has them on the left-hand side without 
parens to be a likely bug.

As for the rest, you can put them where you like. Personally, I put pure, 
nothrow, @safe, @trusted, and @safe on the right and put all of the others 
(i.e. the ones from other languages) on the left.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list