www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Mea Culpa

reply Walter Bright <newshound1 digitalmars.com> writes:
I know that many of you have asked that the compiler diagnose an error for:

    Class C { }
    C c;
    if (c != null)
        ...

because it will seg fault at runtime (depending on how opEqual() was 
written). I resisted because there is no way, in the general case, to 
detect at compile time if one of the operands will evaluate to null or 
not. But I finally thought "most of the cases, null is used directly", 
so I put in a test in the compiler which rejects class == and != with 
the literal null.

I found some errors in my own D code with it.

You guys were right.

The compiler will now also reject things like:

     if (c > null)

which make no sense.
Mar 04 2008
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Walter Bright wrote:
 I know that many of you have asked that the compiler diagnose an error for:
 
    Class C { }
    C c;
    if (c != null)
        ...
 
 because it will seg fault at runtime (depending on how opEqual() was 
 written). I resisted because there is no way, in the general case, to 
 detect at compile time if one of the operands will evaluate to null or 
 not. But I finally thought "most of the cases, null is used directly", 
 so I put in a test in the compiler which rejects class == and != with 
 the literal null.
 
 I found some errors in my own D code with it.
 
 You guys were right.
 
 The compiler will now also reject things like:
 
     if (c > null)
 
 which make no sense.

Yea! It helps to eat your own dog food once in a while. --bb
Mar 04 2008
prev sibling next sibling parent Robert Fraser <fraserofthenight gmail.com> writes:
Walter Bright wrote:
 I know that many of you have asked that the compiler diagnose an error for:
 
    Class C { }
    C c;
    if (c != null)
        ...
 
 because it will seg fault at runtime (depending on how opEqual() was 
 written). I resisted because there is no way, in the general case, to 
 detect at compile time if one of the operands will evaluate to null or 
 not. But I finally thought "most of the cases, null is used directly", 
 so I put in a test in the compiler which rejects class == and != with 
 the literal null.
 
 I found some errors in my own D code with it.
 
 You guys were right.
 
 The compiler will now also reject things like:
 
     if (c > null)
 
 which make no sense.

Thanks! But it did help me develop the good habit of always putting null on the left hand side of comparison tests.
Mar 05 2008
prev sibling next sibling parent Ary Borenszweig <ary esperanto.org.ar> writes:
Thanks!

I wanted to implement that functionality by adding it to the port in 
Descent, but I reverted because then some errors appeared in phobos, and 
I thought I got the logic wrong. Maybe those errors were legitimate 
after all... :)

Walter Bright escribió:
 I know that many of you have asked that the compiler diagnose an error for:
 
    Class C { }
    C c;
    if (c != null)
        ...
 
 because it will seg fault at runtime (depending on how opEqual() was 
 written). I resisted because there is no way, in the general case, to 
 detect at compile time if one of the operands will evaluate to null or 
 not. But I finally thought "most of the cases, null is used directly", 
 so I put in a test in the compiler which rejects class == and != with 
 the literal null.
 
 I found some errors in my own D code with it.
 
 You guys were right.
 
 The compiler will now also reject things like:
 
     if (c > null)
 
 which make no sense.

Mar 05 2008
prev sibling next sibling parent Derek Parnell <derek psych.ward> writes:
On Tue, 04 Mar 2008 22:56:24 -0800, Walter Bright wrote:

 You guys were right.

Thanks, I appreciate your candor. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Mar 05 2008
prev sibling next sibling parent Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Great! Thanks :)
Mar 05 2008
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
Walter,

Thank you thank you.

-Steve 
Mar 05 2008
prev sibling next sibling parent reply Jason House <jason.james.house gmail.com> writes:
Walter Bright wrote:

 I know that many of you have asked that the compiler diagnose an error
 for:
 
     Class C { }
     C c;
     if (c != null)
         ...
 
 because it will seg fault at runtime (depending on how opEqual() was
 written). I resisted because there is no way, in the general case, to
 detect at compile time if one of the operands will evaluate to null or
 not. But I finally thought "most of the cases, null is used directly",
 so I put in a test in the compiler which rejects class == and != with
 the literal null.
 
 I found some errors in my own D code with it.
 
 You guys were right.
 
 The compiler will now also reject things like:
 
      if (c > null)
 
 which make no sense.

While on the topic of null-based problems, are there any plans to address either of the following issues? 1. Run-time debug mode checks for null references. (Maybe -debug=null or something...) 2. Any simplification of forcing non-null function inputs. Example: void foo(A a, B b, C c, D d) in{ assert(a !is null, "foo can't accept null for 1st parameter"); assert(b !is null, "foo can't accept null for 2nd parameter"); assert(c !is null, "foo can't accept null for 3rd parameter"); assert(d !is null, "foo can't accept null for 4th parameter"); } body{...} I know #1 was asked for a few times. #2 is my own personal wish. I find that I'm usually too lazy to add !is null checks all over the place. I guess you could say it's the reverse of C#'s "T?" that allows nulls.
Mar 06 2008
next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Jason House escribió:
 Walter Bright wrote:
 
 I know that many of you have asked that the compiler diagnose an error
 for:

     Class C { }
     C c;
     if (c != null)
         ...

 because it will seg fault at runtime (depending on how opEqual() was
 written). I resisted because there is no way, in the general case, to
 detect at compile time if one of the operands will evaluate to null or
 not. But I finally thought "most of the cases, null is used directly",
 so I put in a test in the compiler which rejects class == and != with
 the literal null.

 I found some errors in my own D code with it.

 You guys were right.

 The compiler will now also reject things like:

      if (c > null)

 which make no sense.

While on the topic of null-based problems, are there any plans to address either of the following issues? 1. Run-time debug mode checks for null references. (Maybe -debug=null or something...) 2. Any simplification of forcing non-null function inputs. Example: void foo(A a, B b, C c, D d) in{ assert(a !is null, "foo can't accept null for 1st parameter"); assert(b !is null, "foo can't accept null for 2nd parameter"); assert(c !is null, "foo can't accept null for 3rd parameter"); assert(d !is null, "foo can't accept null for 4th parameter"); } body{...} I know #1 was asked for a few times. #2 is my own personal wish. I find that I'm usually too lazy to add !is null checks all over the place. I guess you could say it's the reverse of C#'s "T?" that allows nulls.

Or like T! in Spec# :-)
Mar 06 2008
parent bearophile <bearophileHUGS lycos.com> writes:
Ary Borenszweig:
 Or like T! in Spec# :-)

You may take a look at how Cyclone too manages such problem: http://en.wikipedia.org/wiki/Cyclone_programming_language#Pointer.2Freference_types Bye, bearophile
Mar 06 2008
prev sibling next sibling parent reply kov_serg <kov_serg freemail.ru> writes:
Jason House Wrote:
...
 2. Any simplification of forcing non-null function inputs.
    Example:
      void foo(A a, B b, C c, D d)
      in{
        assert(a !is null, "foo can't accept null for 1st parameter");
        assert(b !is null, "foo can't accept null for 2nd parameter");
        assert(c !is null, "foo can't accept null for 3rd parameter");
        assert(d !is null, "foo can't accept null for 4th parameter");
      }
      body{...}
 

I wounder are rules "in" and "out" inherited for virtual function or I should write them every time? Is where any posibilities to inherits such rules except mixin?
Mar 06 2008
parent reply Jason House <jason.james.house gmail.com> writes:
kov_serg wrote:

 Jason House Wrote:
 ...
 2. Any simplification of forcing non-null function inputs.
    Example:
      void foo(A a, B b, C c, D d)
      in{
        assert(a !is null, "foo can't accept null for 1st parameter");
        assert(b !is null, "foo can't accept null for 2nd parameter");
        assert(c !is null, "foo can't accept null for 3rd parameter");
        assert(d !is null, "foo can't accept null for 4th parameter");
      }
      body{...}
 

I wounder are rules "in" and "out" inherited for virtual function or I should write them every time? Is where any posibilities to inherits such rules except mixin?

See http://www.digitalmars.com/d/1.0/dbc.html or http://www.digitalmars.com/d/2.0/dbc.html I'm not sure if I agree completely with the rules, but they make sense. I completely agree with those rules for interfaces, but it seems to partially limit use of contracts for code testing.
Mar 06 2008
next sibling parent Robert Fraser <fraserofthenight gmail.com> writes:
Jason House wrote:
 kov_serg wrote:
 
 Jason House Wrote:
 ...
 2. Any simplification of forcing non-null function inputs.
    Example:
      void foo(A a, B b, C c, D d)
      in{
        assert(a !is null, "foo can't accept null for 1st parameter");
        assert(b !is null, "foo can't accept null for 2nd parameter");
        assert(c !is null, "foo can't accept null for 3rd parameter");
        assert(d !is null, "foo can't accept null for 4th parameter");
      }
      body{...}

I wounder are rules "in" and "out" inherited for virtual function or I should write them every time? Is where any posibilities to inherits such rules except mixin?

See http://www.digitalmars.com/d/1.0/dbc.html or http://www.digitalmars.com/d/2.0/dbc.html I'm not sure if I agree completely with the rules, but they make sense. I completely agree with those rules for interfaces, but it seems to partially limit use of contracts for code testing.

That part of the spec (contract inheritance) is not actually implemented ;-P. There's no inheritance of contracts using either of newest DMDs (not sure about GDC...).
Mar 06 2008
prev sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Jason House wrote:
 kov_serg wrote:
 
 Jason House Wrote:
 ...
 I wounder are rules "in" and "out" inherited for virtual function or I
 should write them every time? Is where any posibilities to inherits such
 rules except mixin?

See http://www.digitalmars.com/d/1.0/dbc.html or http://www.digitalmars.com/d/2.0/dbc.html

Theoretically they are inherited as described in the spec pages linked above, but AFAIK this isn't actually implemented in DMD and GDC... (See <http://d.puremagic.com/issues/show_bug.cgi?id=302>)
Mar 06 2008
parent Jason House <jason.james.house gmail.com> writes:
Frits van Bommel wrote:

 Jason House wrote:
 kov_serg wrote:
 
 Jason House Wrote:
 ...
 I wounder are rules "in" and "out" inherited for virtual function or I
 should write them every time? Is where any posibilities to inherits such
 rules except mixin?

See http://www.digitalmars.com/d/1.0/dbc.html or http://www.digitalmars.com/d/2.0/dbc.html

Theoretically they are inherited as described in the spec pages linked above, but AFAIK this isn't actually implemented in DMD and GDC... (See <http://d.puremagic.com/issues/show_bug.cgi?id=302>)

{grumble} I'll refrain from ranting about the quality of D documentation...
Mar 06 2008
prev sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
Jason House wrote:
 Walter Bright wrote:
 
 I know that many of you have asked that the compiler diagnose an error
 for:

     Class C { }
     C c;
     if (c != null)
         ...

 because it will seg fault at runtime (depending on how opEqual() was
 written). I resisted because there is no way, in the general case, to
 detect at compile time if one of the operands will evaluate to null or
 not. But I finally thought "most of the cases, null is used directly",
 so I put in a test in the compiler which rejects class == and != with
 the literal null.

 I found some errors in my own D code with it.

 You guys were right.

 The compiler will now also reject things like:

      if (c > null)

 which make no sense.

While on the topic of null-based problems, are there any plans to address either of the following issues? 1. Run-time debug mode checks for null references. (Maybe -debug=null or something...)

Or just catching SIGSEGV and throwing an exception.
 2. Any simplification of forcing non-null function inputs.
    Example:
      void foo(A a, B b, C c, D d)
      in{
        assert(a !is null, "foo can't accept null for 1st parameter");
        assert(b !is null, "foo can't accept null for 2nd parameter");
        assert(c !is null, "foo can't accept null for 3rd parameter");
        assert(d !is null, "foo can't accept null for 4th parameter");
      }
      body{...}
 
 I know #1 was asked for a few times.  #2 is my own personal wish.  I find
 that I'm usually too lazy to add !is null checks all over the place.  I
 guess you could say it's the reverse of C#'s "T?" that allows nulls.

If you use my assertions library, that's slightly shorter, with a relevant error message: expect(a).not.isNull; It'll print: "expected: not null but was: null" Or something like that. I'm having trouble compiling stuff with the latest Tango; undefined ModuleInfo grrrrrrr... I love D, but I dislike DMD.
Mar 06 2008
parent reply Jason House <jason.james.house gmail.com> writes:
Christopher Wright wrote:
 Jason House wrote:
 1. Run-time debug mode checks for null references.
    (Maybe -debug=null or something...)

Or just catching SIGSEGV and throwing an exception.

Can you provide a link to code that does this correctly for all the latest D compilers? I have yet to find code that works for me in all cases (I have copied and pasted a few variants into my code without success). I'm thinking of dmd 1.x, dmd 2.x, and gdc 0.24... As well as windows, linux, mac, 64 bit windows, and 64 bit linux.
Mar 07 2008
next sibling parent Sean Kelly <sean invisibleduck.org> writes:
== Quote from Jason House (jason.james.house gmail.com)'s article
 Christopher Wright wrote:
 Jason House wrote:
 1. Run-time debug mode checks for null references.
    (Maybe -debug=null or something...)

Or just catching SIGSEGV and throwing an exception.

compilers? I have yet to find code that works for me in all cases (I have copied and pasted a few variants into my code without success). I'm thinking of dmd 1.x, dmd 2.x, and gdc 0.24... As well as windows, linux, mac, 64 bit windows, and 64 bit linux.

It's not technically legal to throw an exception from a signal handler, though it seems to actually work on many OSes. Sean
Mar 07 2008
prev sibling parent Christopher Wright <dhasenan gmail.com> writes:
Jason House wrote:
 Can you provide a link to code that does this correctly for all the latest D
 compilers?  I have yet to find code that works for me in all cases (I have
 copied and pasted a few variants into my code without success).  I'm
 thinking of dmd 1.x, dmd 2.x, and gdc 0.24...  As well as windows, linux,
 mac, 64 bit windows, and 64 bit linux.

No.
Mar 07 2008
prev sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Walter Bright wrote:
 I know that many of you have asked that the compiler diagnose an error for:
 
    Class C { }
    C c;
    if (c != null)
        ...
 
 because it will seg fault at runtime (depending on how opEqual() was 
 written). I resisted because there is no way, in the general case, to 
 detect at compile time if one of the operands will evaluate to null or 
 not. But I finally thought "most of the cases, null is used directly", 
 so I put in a test in the compiler which rejects class == and != with 
 the literal null.
 
 I found some errors in my own D code with it.
 
 You guys were right.
 
 The compiler will now also reject things like:
 
     if (c > null)
 
 which make no sense.

This is spectacular. The new check found 3 of these puppies in my code, just waiting to bite me. --bb
Mar 09 2008