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