dmd 2.063 beta 5
Steven Schveighoffer
schveiguy at yahoo.com
Fri May 24 06:46:48 PDT 2013
On Fri, 24 May 2013 07:57:51 -0400, Don <turnyourkidsintocash at nospam.com>
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
>>> <art.08.09 at gmail.com> 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
More information about the Digitalmars-d-announce
mailing list