View mode: basic / threaded / horizontal-split · Log in · Help
March 07, 2005
consts by another name
I know that asking for the full ramifications of const is a never-gonna-happen, but I sorely miss one of the most 
useful, and relatively simple, applications of this amazingly powerful little keyword in C++: that of guaranteeing 
initialisation.

My Database class has the following members.

   uint        m_flags;
   size_type   m_numLines;
   Record[]    m_records;
   Field[]     m_fields;

Construction of an instance of Database is a non-trivial (i.e. far from atomic) operation. The processing of a database 
file involves parsing content into fields and then gathering fields into records.

Since databases may be instantiated from more than one format, factoring out initialisation between multiple 
constructors increases the likelihood of errors in initialisation of the members.

Since, in C++ (rant, rant, rant), I am used to, and rather good at, having the compiler detect such things for me, I 
sorely miss this in D.

So, what I'd like is some construct (and maybe 'final' can be it) that gives an error *at compile time* if a variable so 
marked has not been initialised during any constructor.

Since I'm somewhat rusty, I've just spent some time perusing the docs, but can't find anything pertaining to final. And 
it's a trivial matter to introduce an uninitialised final member which causes the compiler no consternation.

So, are there any serious objections to this behaviour, through final or another keyword, because this is another area 
in which D is (currently) manifestly deficient wrt C++?

Matthew
March 07, 2005
Re: consts by another name
ha! I bloody well missed one: m_numLines.

:-(


"Matthew" <admin.hat@stlsoft.dot.org> wrote in message news:d0h8ni$22cc$1@digitaldaemon.com...
>I know that asking for the full ramifications of const is a never-gonna-happen, but I sorely miss one of the most 
>useful, and relatively simple, applications of this amazingly powerful little keyword in C++: that of guaranteeing 
>initialisation.
>
> My Database class has the following members.
>
>    uint        m_flags;
>    size_type   m_numLines;
>    Record[]    m_records;
>    Field[]     m_fields;
>
> Construction of an instance of Database is a non-trivial (i.e. far from atomic) operation. The processing of a 
> database file involves parsing content into fields and then gathering fields into records.
>
> Since databases may be instantiated from more than one format, factoring out initialisation between multiple 
> constructors increases the likelihood of errors in initialisation of the members.
>
> Since, in C++ (rant, rant, rant), I am used to, and rather good at, having the compiler detect such things for me, I 
> sorely miss this in D.
>
> So, what I'd like is some construct (and maybe 'final' can be it) that gives an error *at compile time* if a variable 
> so marked has not been initialised during any constructor.
>
> Since I'm somewhat rusty, I've just spent some time perusing the docs, but can't find anything pertaining to final. 
> And it's a trivial matter to introduce an uninitialised final member which causes the compiler no consternation.
>
> So, are there any serious objections to this behaviour, through final or another keyword, because this is another area 
> in which D is (currently) manifestly deficient wrt C++?
>
> Matthew
>
>
>
March 07, 2005
Re: consts by another name
"Matthew" <admin.hat@stlsoft.dot.org> wrote in message 
news:d0h8ni$22cc$1@digitaldaemon.com...
>I know that asking for the full ramifications of const is a 
>never-gonna-happen, but I sorely miss one of the most useful, and 
>relatively simple, applications of this amazingly powerful little keyword 
>in C++: that of guaranteeing initialisation.
>
> My Database class has the following members.
>
>    uint        m_flags;
>    size_type   m_numLines;
>    Record[]    m_records;
>    Field[]     m_fields;
>
> Construction of an instance of Database is a non-trivial (i.e. far from 
> atomic) operation. The processing of a database file involves parsing 
> content into fields and then gathering fields into records.
>
> Since databases may be instantiated from more than one format, factoring 
> out initialisation between multiple constructors increases the likelihood 
> of errors in initialisation of the members.
>
> Since, in C++ (rant, rant, rant), I am used to, and rather good at, having 
> the compiler detect such things for me, I sorely miss this in D.
>
> So, what I'd like is some construct (and maybe 'final' can be it) that 
> gives an error *at compile time* if a variable so marked has not been 
> initialised during any constructor.

Java allows "final" on fields and local variables, which means the variable 
can only be assigned to once. When I looked up the exact spec 
http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#10931 
it turns out it also allows "blank final" variables which means there isn't 
an initializer so it isn't quite the same as what you are proposing. I don't 
know how well this would work out with D's inout and out parameters but it's 
worth a shot IMO.
March 07, 2005
Re: consts by another name
"Matthew" <admin.hat@stlsoft.dot.org> wrote in message
news:d0h8ni$22cc$1@digitaldaemon.com...
> I know that asking for the full ramifications of const is a
never-gonna-happen, but I sorely miss one of the most
> useful, and relatively simple, applications of this amazingly powerful
little keyword in C++: that of guaranteeing
> initialisation.
>
> My Database class has the following members.
>
>     uint        m_flags;
>     size_type   m_numLines;
>     Record[]    m_records;
>     Field[]     m_fields;
>
> Construction of an instance of Database is a non-trivial (i.e. far from
atomic) operation. The processing of a database
> file involves parsing content into fields and then gathering fields into
records.
>
> Since databases may be instantiated from more than one format, factoring
out initialisation between multiple
> constructors increases the likelihood of errors in initialisation of the
members.

The way to deal with that is to use "forwarding constructors", a feature
proposed for C++ but not implemented. It's implemented in D. D will also
provide a default initializer, or a user specified default initializer,
guaranteeing that all members are initialized, instead of the C++ way of
leaving such things undefined.

> Since, in C++ (rant, rant, rant), I am used to, and rather good at, having
the compiler detect such things for me, I
> sorely miss this in D.

That would only be for const members in C++. Non const C++ members get no
detection at all, not at compile time, not at runtime. The members just
contain uninitialized garbage.

> So, what I'd like is some construct (and maybe 'final' can be it) that
gives an error *at compile time* if a variable so
> marked has not been initialised during any constructor.
> Since I'm somewhat rusty, I've just spent some time perusing the docs, but
can't find anything pertaining to final. And
> it's a trivial matter to introduce an uninitialised final member which
causes the compiler no consternation.
>
> So, are there any serious objections to this behaviour, through final or
another keyword, because this is another area
> in which D is (currently) manifestly deficient wrt C++?

I see your point about wanting the compiler to give an error on
uninitialized members, but in D, members are not uninitialized. C++ only
gives such errors for const members. For non const members, C++ gives no
help at all. And I understand that you've said you've rarely had a problem
with this, but I have, and it's a nasty deficiency in C++. I guess I just am
not understanding why not initializing const members is a manifest
deficiency, while not initializing non-const members is not much of an
issue.
March 07, 2005
Re: consts by another name
Here's another way you can use forwarding constructors. Given:

class C
{
   int a, b, c;
}

create a constructor:

   this(int a, int b, int c) { this.a = a; this.b = b; this.c = c; }

Then, for your multitude of constructor needs, forward the actual member
initialization to the above this():

   this(MyParameter p)
   {
           ...
           this(exp1, exp2, exp3);
   }

Then, if you add a member d:

   int a, b, c, d;

and add it to the forwarding constructor:

   this(int a, int b, int c, int d) { this.a = a; this.b = b; this.c = c;
this.d = d; }

then any constructors that are not so updated will cause an error.
March 07, 2005
Re: consts by another name
"Ben Hinkle" <bhinkle@mathworks.com> wrote in message news:d0hur9$2peg$1@digitaldaemon.com...
>
> "Matthew" <admin.hat@stlsoft.dot.org> wrote in message news:d0h8ni$22cc$1@digitaldaemon.com...
>>I know that asking for the full ramifications of const is a never-gonna-happen, but I sorely miss one of the most 
>>useful, and relatively simple, applications of this amazingly powerful little keyword in C++: that of guaranteeing 
>>initialisation.
>>
>> My Database class has the following members.
>>
>>    uint        m_flags;
>>    size_type   m_numLines;
>>    Record[]    m_records;
>>    Field[]     m_fields;
>>
>> Construction of an instance of Database is a non-trivial (i.e. far from atomic) operation. The processing of a 
>> database file involves parsing content into fields and then gathering fields into records.
>>
>> Since databases may be instantiated from more than one format, factoring out initialisation between multiple 
>> constructors increases the likelihood of errors in initialisation of the members.
>>
>> Since, in C++ (rant, rant, rant), I am used to, and rather good at, having the compiler detect such things for me, I 
>> sorely miss this in D.
>>
>> So, what I'd like is some construct (and maybe 'final' can be it) that gives an error *at compile time* if a variable 
>> so marked has not been initialised during any constructor.
>
> Java allows "final" on fields and local variables, which means the variable can only be assigned to once. When I 
> looked up the exact spec http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#10931 it turns 
> out it also allows "blank final" variables which means there isn't an initializer so it isn't quite the same as what 
> you are proposing.

Damn. Well I always say Java's a stinking pile of crap ...

> I don't know how well this would work out with D's inout and out parameters but it's worth a shot IMO.

I only care - at the moment at least - about the compiler guaranteeing at runtime that a variable is explicitly 
initialised. I cannot imagine that this is terribly hard - although a compiler writer I'm not.
March 07, 2005
Re: consts by another name
"Walter" <newshound@digitalmars.com> wrote in message news:d0i8qe$3ml$1@digitaldaemon.com...
>
> "Matthew" <admin.hat@stlsoft.dot.org> wrote in message
> news:d0h8ni$22cc$1@digitaldaemon.com...
>> I know that asking for the full ramifications of const is a
> never-gonna-happen, but I sorely miss one of the most
>> useful, and relatively simple, applications of this amazingly powerful
> little keyword in C++: that of guaranteeing
>> initialisation.
>>
>> My Database class has the following members.
>>
>>     uint        m_flags;
>>     size_type   m_numLines;
>>     Record[]    m_records;
>>     Field[]     m_fields;
>>
>> Construction of an instance of Database is a non-trivial (i.e. far from
> atomic) operation. The processing of a database
>> file involves parsing content into fields and then gathering fields into
> records.
>>
>> Since databases may be instantiated from more than one format, factoring
> out initialisation between multiple
>> constructors increases the likelihood of errors in initialisation of the
> members.
>
> The way to deal with that is to use "forwarding constructors", a feature
> proposed for C++ but not implemented.

Off the point entirely.

> It's implemented in D. D will also
> provide a default initializer, or a user specified default initializer,
> guaranteeing that all members are initialized, instead of the C++ way of
> leaving such things undefined.

Yeah. And therefore it won't warn about an uninitialised variable.

Score yet another win for C++ over D!

:-(

>
>> Since, in C++ (rant, rant, rant), I am used to, and rather good at, having
> the compiler detect such things for me, I
>> sorely miss this in D.
>
> That would only be for const members in C++. Non const C++ members get no
> detection at all, not at compile time, not at runtime. The members just
> contain uninitialized garbage.

True. But not the point, since I'm asking for a keyword that can be applied at the programmer's discretion, not a 
general behaviour for all member variables.

>> So, what I'd like is some construct (and maybe 'final' can be it) that
> gives an error *at compile time* if a variable so
>> marked has not been initialised during any constructor.
>> Since I'm somewhat rusty, I've just spent some time perusing the docs, but
> can't find anything pertaining to final. And
>> it's a trivial matter to introduce an uninitialised final member which
> causes the compiler no consternation.
>>
>> So, are there any serious objections to this behaviour, through final or
> another keyword, because this is another area
>> in which D is (currently) manifestly deficient wrt C++?
>
> I see your point about wanting the compiler to give an error on
> uninitialized members, but in D, members are not uninitialized.

Oh come on! I'm nearly 37, .and I've lost nearly a centimetre of hairline in the last five years. You're gonna have me 
tearing out all the rest if you carry on like this.

Yes, I know I said uninitialised, but you know I meant "not explicitly initialised". Sigh

> C++ only
> gives such errors for const members.

Oh really?
   References?
   Members of class type with non-default constructors?

> For non const members, C++ gives no
> help at all.

True. But C++ compilers do!!!!

> And I understand that you've said you've rarely had a problem
> with this, but I have, and it's a nasty deficiency in C++.

So, if some proportion of the community have, and some proportion haven't, is the answer to arbitrarily side with one, 
or to cater for both?

> I guess I just am
> not understanding why not initializing const members is a manifest
> deficiency, while not initializing non-const members is not much of an
> issue.

Well, in one sense, you don't have to understand, do you? The DMC++ compiler provides const, yet you don't understand 
the many excellent uses for this feature.

But this particular facet of C++ const - and I'm only arguing for *this particular facet* going into D - is that I could 
mark my class member variables as, say, 'explicit', and the compiler would then issue an error if any of them are not 
explicitly initialised in all constructors.

The rationale? See my second post on this thread, beginning with "ha!". My first non-trivial class in months has just 
such an error in it.

You may never forget to explicitly initialise member variables in non-trivial classes, but we mortals do. Unless and 
until you can show that this small subset of const's behaviour would result in unacceptable compiler complexity and/or 
programmer confusion, I suggest its absence is a flaw.
March 07, 2005
Re: consts by another name
"Walter" <newshound@digitalmars.com> wrote in message news:d0ibp9$6sf$1@digitaldaemon.com...
> Here's another way you can use forwarding constructors. Given:
>
> class C
> {
>    int a, b, c;
> }
>
> create a constructor:
>
>    this(int a, int b, int c) { this.a = a; this.b = b; this.c = c; }
>
> Then, for your multitude of constructor needs, forward the actual member
> initialization to the above this():
>
>    this(MyParameter p)
>    {
>            ...
>            this(exp1, exp2, exp3);
>    }
>
> Then, if you add a member d:
>
>    int a, b, c, d;
>
> and add it to the forwarding constructor:
>
>    this(int a, int b, int c, int d) { this.a = a; this.b = b; this.c = c;
> this.d = d; }
>
> then any constructors that are not so updated will cause an error.

Sure. I worked all this out in a heartbeat. I also worked out an even nicer (IMO) option using a static private method 
that takes out params.

But this is all entirely off the point of my requirement for (what I'm now calling) 'explicit'.
March 07, 2005
Re: consts by another name
On Tue, 8 Mar 2005 07:59:28 +1100, Matthew wrote:

> "Walter" <newshound@digitalmars.com> wrote in message news:d0ibp9$6sf$1@digitaldaemon.com...
>> Here's another way you can use forwarding constructors. Given:
>>
>> class C
>> {
>>    int a, b, c;
>> }
>>
>> create a constructor:
>>
>>    this(int a, int b, int c) { this.a = a; this.b = b; this.c = c; }
>>
>> Then, for your multitude of constructor needs, forward the actual member
>> initialization to the above this():
>>
>>    this(MyParameter p)
>>    {
>>            ...
>>            this(exp1, exp2, exp3);
>>    }
>>
>> Then, if you add a member d:
>>
>>    int a, b, c, d;
>>
>> and add it to the forwarding constructor:
>>
>>    this(int a, int b, int c, int d) { this.a = a; this.b = b; this.c = c;
>> this.d = d; }
>>
>> then any constructors that are not so updated will cause an error.
> 
> Sure. I worked all this out in a heartbeat. I also worked out an even nicer (IMO) option using a static private method 
> that takes out params.
> 
> But this is all entirely off the point of my requirement for (what I'm now calling) 'explicit'.

Matthew, can I summarize your request thus ...

Would it possible to have some mechanism (eg. a new keyword) that
designates specific class members as 'must have explicit initialization',
and thus have the compiler produce a error message for all such members
that have no explicit initialization in any of the class' constructor
functions.

-- 
Derek
Melbourne, Australia
8/03/2005 9:46:04 AM
March 07, 2005
Re: consts by another name
In article <d0iea8$a20$1@digitaldaemon.com>, Matthew says...
>
>
>"Ben Hinkle" <bhinkle@mathworks.com> wrote in message news:d0hur9$2peg$1@digitaldaemon.com...
>>
>> "Matthew" <admin.hat@stlsoft.dot.org> wrote in message news:d0h8ni$22cc$1@digitaldaemon.com...
>>>I know that asking for the full ramifications of const is a never-gonna-happen, but I sorely miss one of the most 
>>>useful, and relatively simple, applications of this amazingly powerful little keyword in C++: that of guaranteeing 
>>>initialisation.
>>>
>>> My Database class has the following members.
>>>
>>>    uint        m_flags;
>>>    size_type   m_numLines;
>>>    Record[]    m_records;
>>>    Field[]     m_fields;
>>>
>>> Construction of an instance of Database is a non-trivial (i.e. far from atomic) operation. The processing of a 
>>> database file involves parsing content into fields and then gathering fields into records.
>>>
>>> Since databases may be instantiated from more than one format, factoring out initialisation between multiple 
>>> constructors increases the likelihood of errors in initialisation of the members.
>>>
>>> Since, in C++ (rant, rant, rant), I am used to, and rather good at, having the compiler detect such things for me, I 
>>> sorely miss this in D.
>>>
>>> So, what I'd like is some construct (and maybe 'final' can be it) that gives an error *at compile time* if a variable 
>>> so marked has not been initialised during any constructor.
>>
>> Java allows "final" on fields and local variables, which means the variable can only be assigned to once. When I 
>> looked up the exact spec http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#10931 it turns 
>> out it also allows "blank final" variables which means there isn't an initializer so it isn't quite the same as what 
>> you are proposing.
>
>Damn. Well I always say Java's a stinking pile of crap ...

hmm - no wonder you're so grumpy about D. IMO D shares more in common with
Java/C# than with C++.

>> I don't know how well this would work out with D's inout and out parameters but it's worth a shot IMO.
>
>I only care - at the moment at least - about the compiler guaranteeing at runtime that a variable is explicitly 
>initialised. I cannot imagine that this is terribly hard - although a compiler writer I'm not.

Agreed - and it sounds like Walter will get to it eventually.
Top | Discussion index | About this forum | D home