On Fri, 24 May 2013 07:57:51 -0400, Don <[email protected]>
wrote:
On Friday, 24 May 2013 at 10:55:09 UTC, Artur Skawina wrote:
On 05/24/13 02:33, Steven Schveighoffer wrote:
On Thu, 23 May 2013 19:03:25 -0400, Artur Skawina
<[email protected]> wrote:
On 05/23/13 23:06, Steven Schveighoffer wrote:
compiles:
struct S
{
const int x;
this(int n)
{
x = n;
}
}
It's the 'const int x = 42;' case we're talking about. *That* one
does not
compile and doesn't need to. It /could/, but I see no reason to allow
this;
My example is essentially:
const int x = 0;
No, that's not the same.
const int w;
is the same syntax used in C++. It's a declaration without an
initializer. It signals your intention to initialize it later.
This isn't C++. C++ has implicit default constructors that are built
using the given initializations. D does it differently.
Now, D does default-initialize everything, so that there really isn't
any such thing as an uninitialized variable in D, but it still signals
the intention that you will modify it later.
int is a misleading example since the default initializer is 0, and it's
common for people to rely on that.
Better to use char or float, or a class, where the default initializer
is not usable, and it's clearer that it's a bug to use it.
OK, how about this:
struct MyFloat
{
float f = 0.0;
}
struct S
{
const MyFloat x;
}
:P
The only way I can understand this feature is that it is changing the
meaning of initializers inside aggregates.
Previously, they were initializers. Now, they're not. They're setting
the value of .init for the class.
This was ALWAYS the case.
struct S
{
int x = 5; // sets S.init.x to 5
}
You are not looking at the change correctly. The change is simply,
instead of const int x = 5 magically (and incorrectly) implying static, it
doesn't. Then it defaults to the same behavior as non-const member
initializers -- it sets the .init value for the struct. Previously, this
was difficult to do, see my above example.
And they use the same syntax which is used for actual initializers.
They use the same syntax that is used to dictate the init value for
non-const members.
In the past, the compiler didn't check if you from set a field in a
constructor, which you had already initialized with an initializer.
But, it didn't really matter.
With a const field, it makes a much bigger difference, since if an
initializer was specified, the only way that the field can make sense is
if you modify it somewhere else. So the initializer MUST be able to be
overwritten.
This has lead us to this oddity that under the new regime,
const char c = 'e';
is setting the value of c, unless it is inside an aggregate, in which
case it's not initializing c, it's just specifying what .init is for
that struct.
As is the same (and always has been) for all instance member initializers.
char c = 'e';
Hence, you are arguing for a change in behavior. And the arguments for
that
are extremely weak. The goal should be to allow const initialization to
happen
exactly once.
I agree. This is the crux of the argument.
Are you and I the the only ones who see that as a valuable property of
the language? I'm astonished that others are so willing to sacrifice it.
It's still available, just put static on the member, and it's the same as
before.
-Steve