July 11, 2008
On Thu, 10 Jul 2008 20:31:02 -0400, Nick Sabalausky wrote:

> "Bill Baxter" <dnewsgroup@billbaxter.com> wrote in message news:g561hh$2g6g$2@digitalmars.com...
>> Leandro Lucarella wrote:
>>> Walter Bright, el  9 de julio a las 13:41 me escribiste:
>>>> Piping the output into a file and then perusing it manually looking for warning statements is never going to happen.
>>>
>>> I code using VIM. VIM has a very convenient feature that recolects the
>>> make (compiler output) and let you you iterate over warnings/errors
>>> (using
>>> :cn, and :cp). So yes. It's going to happen. It happens all the time.
>>>
>>> And I think most decent IDEs/Editor do that, so it's not something VIM-specific.
>>
>> Emacs has it too!  M-x `
>>
>>
> Every IDE I've ever used does it. And I'm constantly IDE-hopping.

Currently, I use IDE only if forced to do so. Kate/nedit & make & tee does everything I need ;)
July 11, 2008
On Thu, 10 Jul 2008 20:53:53 +0100, Bruce Adams wrote:

> Generally there are two types of code. Code for which warnings are
> allowed and warning free code. Transitioning from code that's been
> allowed to have warnings
> for a long time to warning free code takes effort. I still think the
> long term benefits make it worth it.

I so totally agree with this! "me too"...
July 11, 2008
Bruce Adams wrote:
> On Thu, 10 Jul 2008 11:20:21 +0100, Don <nospam@nospam.com.au> wrote:
> 
>> Bruce Adams wrote:
> 
>>>  I would contend this is a problem with the quality of headers provided by M$.
>>> Library code has a greater need to be high quality than regular code.
>>> Operating system APIs even more so.
>>> Removing warnings from C/C++ headers requires you to write them carefully to
>>> remove the ambiguity that leads to the warning. That is, this definition of
>>> quality is a measure that increases with decreasing semantic ambiguity.
>>
>> I think it's a complete fallacy to think that lower-number-of-warnings is proportional to better-code-quality.
>> Once a warning is so spurious (eg, so that it has a <1% chance of being an error), it's more likely that you'll introduce an error in getting rid of the warning.
>> In C++, error-free code is clearly defined in the spec. But warning-free
>> code is not in the spec. You're at the mercy of any compiler writer who decides to put in some poorly thought out, idiotic warning.
>>
> I didn't say that *overall* quality is related to lower warnings but it is a factor.
> There are other factors that are typically more significant. Still given the choice between
> code with some warnings and warning free code all other things being equal I would
> pick the warning free code. You obviously shift your quality measure towards that
> aspect of readability. Personally I think the impact on readability is minimal.

I don't care about readability so much as correctness.
My point is that sometimes making code warning-free makes it WORSE.
It depends on the quality of the warning. Some are hugely beneficial.

> 
>> If you insist on avoiding all warnings, you're effectively using the programming language spec which one individual has carelessly made on a whim.
>>
> While some warnings are less useful than others I don't think its fair in
> general to say they're introduced carelessly on a whim.

The VC6 ones certainly seemed to be.
Generation of a warning by a compiler is something that deserves almost as much care as a language specification. In the C++ world I really haven't seen evidence that much care is taken.


>> For example, VC6 generates some utterly ridiculous warnings. In some cases, the chance of it being a bug is not small, it is ZERO.
>>
> Before they got Herb Sutter on board VC++ was notoriously bad.
> If that's true then it would be a compiler bug. If you know it to be true
> you can disable the warning with a pragma. Similarly in gcc all warnings are
> supposed to have an on/off switch. So you get to choose which warnings
> you think are important. I am well aware that some people choose to ignore
> all warnings in order to code faster. In general its a false economy like
> not writing unit-tests.

That's totally different. The issue is not that "generating warning-free code is more work". Rather, the problem is when there is no reasonable way to make the warning go away, that doesn't involve writing incorrect code.

>> In DMD, the signed/unsigned mismatch warning is almost always spurious. Getting rid of it reduces code quality.
> 
> I have encountered quite a few bugs (in C++) relating to unsigned/signed
> mismatches. Its a very subtle and hard to spot problem when a simple addition
> suddenly changes the sign of your result. It costs a ugly cast to remove the
> warning but that is a trade I'm prepared to make to never have to worry about
> such bugs.

(1) casts can hide far more serious errors. You want to say, "I know this is a signed-unsigned mismatch, but I know it is ok in this instance". But what you are saying is, "Please change the type of this variable. No matter what it is, turn it into an int".
(2) In DMD, the signed/unsigned error (as it exists today) really is garbage. I've had to introduce incorrect code (via casts) into both Tango and Phobos in order to satisfy it.

July 11, 2008
superdan wrote:
> Nick Sabalausky Wrote:
> 
>> As just a few examples:
>> http://www.digitalmars.com/d/1.0/warnings.html
> 
> yarp i'm so happy you sent those. let's take'em 1 by 1. please let me know agree or disagree. 
> 
> 1. warning - implicit conversion of expression expr of type type to type can cause loss of data
> 
> it's a shame this is allowed at all. any conversion that involves a loss must require a cast right there. as far as the example give goes:
> 
> byte a, b;
> byte c = a + b;
> 
> compiler can't know a + b is in byte range so a cast is good. but take this now:
> 
> byte c = a & b;
> 
> in this case the compiler must accept code. so what i'm saying is that better operator types will help a ton.

That's in bugzilla.

http://d.puremagic.com/issues/show_bug.cgi?id=1257

That whole area needs to be tidied up. Polysemous types should really help with this.

> 3. warning - no return at end of function
> 
> now what a sick decision was it to accept that in the first place. an overwhelming percentage of functions *can* and *will* be written to have a meaningful return at the end. then why the fuck cater for the minority and hurt everybody else. just require a return or throw and call it a day. people who can't return something meaningful can just put a throw. code growth is negligible. impact on speed is virtually nil. why the hell do we even bother arguing over it.

Yup.
return should be required, unless function contains inline asm.
Otherwise manually put assert(0); at the last line.

> 4. warning - switch statement has no default
> 
> another example of a motherfuck. just require total coverage. in closed-set cases i routinely write anyway:
> 
> switch (crap) {
> case a: ...; break;
> case b: ...; break;
> default: assert(crap == c): ...; break;
> }
> 
> again: vast majority of code already has a default. the minority just has to add a little code. make it an error.

Yup. Make it an error.

> 
> 5. warning - statement is not reachable
> 
> this is a tad more messy. people routinely insert a premature return in there to check for stuff. it pisses me off when that won't compile. i discovered i could do this:
> 
> if (true) return crap;
> 
> that takes care of the error. and i think it's actually good for me because it really is supposed to be temporary code. it jumps at me in a review. as it should.

You can also put assert(0); at the top of the unreachable code.

2,3, and 4 should definitely be errors.
I also think that uninitialised class variables should be a compile-time error. It's a horrible newbie trap, especially for anyone with a C++ background:
-------------
class C {
  void hello() { writefln("Hello crashing world"); }
};

void main()  {
 C c;  // should be illegal
 c.hello();
}
--------------
My first D program using classes was somewhat like that; took me ages to work out why it was segfaulting at runtime. It's still the most common mistake I make.
You should have to write C c = null; for the rare cases where you really want an uninitialised class.

July 11, 2008
Don Wrote:

> superdan wrote:
> > Nick Sabalausky Wrote:
> > 
> >> As just a few examples: http://www.digitalmars.com/d/1.0/warnings.html
> > 
> > yarp i'm so happy you sent those. let's take'em 1 by 1. please let me know agree or disagree.
> > 
> > 1. warning - implicit conversion of expression expr of type type to type can cause loss of data
> > 
> > it's a shame this is allowed at all. any conversion that involves a loss must require a cast right there. as far as the example give goes:
> > 
> > byte a, b;
> > byte c = a + b;
> > 
> > compiler can't know a + b is in byte range so a cast is good. but take this now:
> > 
> > byte c = a & b;
> > 
> > in this case the compiler must accept code. so what i'm saying is that better operator types will help a ton.
> 
> That's in bugzilla.
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=1257

cool that's great. just a nit now. you mention only logical operations there. (actually you meant bitwise operation.) but i got to thinking a bit and a few integer arithmetic operations also should be included. a / b is never larger than a (cept for signed/unsigned mixed shit). a % b is never larger than b (again save for same shit). this could go a long way making casts unnecessary. as a consequence the compiler could tighten its sphincters and become more strict about implicit casts & shit.

someone else also mentioned a < b which is fucked for mixed signs. all ordering comparisons like that are fucked and should be disabled. only == and != work for mixed signs. for the rest, cast must be required. of course if one is constant there may be no need.

i have no idea on what to do about a + b with mixed signs. it's messed up like shit.

> That whole area needs to be tidied up. Polysemous types should really help with this.

could someone care explain what this polysemous shit is (is it not polysemantic btw). the video is too vague about it. maybe this will convince andrey to haul his russian ass over here. btw thought he'd be older and more self-righteous. but i was surprised he seems a laid back dood. tries too hard to be funny tho. but he knows his shit.

> > 3. warning - no return at end of function
> > 
> > now what a sick decision was it to accept that in the first place. an overwhelming percentage of functions *can* and *will* be written to have a meaningful return at the end. then why the fuck cater for the minority and hurt everybody else. just require a return or throw and call it a day. people who can't return something meaningful can just put a throw. code growth is negligible. impact on speed is virtually nil. why the hell do we even bother arguing over it.
> 
> Yup.
> return should be required, unless function contains inline asm.
> Otherwise manually put assert(0); at the last line.

i don't think assert(0); is cool. in a release build it disappears and that fucks the whole plan right there.

> > 4. warning - switch statement has no default
> > 
> > another example of a motherfuck. just require total coverage. in closed-set cases i routinely write anyway:
> > 
> > switch (crap)
> > {
> > case a: ...; break;
> > case b: ...; break;
> > default: assert(crap == c): ...; break;
> > }
> > 
> > again: vast majority of code already has a default. the minority just has to add a little code. make it an error.
> 
> Yup. Make it an error.

great! where do i sign the petition?

> > 5. warning - statement is not reachable
> > 
> > this is a tad more messy. people routinely insert a premature return in there to check for stuff. it pisses me off when that won't compile. i discovered i could do this:
> > 
> > if (true) return crap;
> > 
> > that takes care of the error. and i think it's actually good for me because it really is supposed to be temporary code. it jumps at me in a review. as it should.
> 
> You can also put assert(0); at the top of the unreachable code.

again assert(0); goes away in release mode. but wait, that's unreachable code anyway. guess that could work.

> 2,3, and 4 should definitely be errors.
> I also think that uninitialised class variables should be a compile-time
> error. It's a horrible newbie trap, especially for anyone with a C++
> background:
> -------------
> class C {
>    void hello() { writefln("Hello crashing world"); }
> };
> 
> void main()  {
>   C c;  // should be illegal
>   c.hello();
> }
> --------------
> My first D program using classes was somewhat like that; took me ages to
> work out why it was segfaulting at runtime. It's still the most common
> mistake I make.
> You should have to write C c = null; for the rare cases where you really
> want an uninitialised class.

yarp. can't tell how many times this bit my ass. in fact even "new" is bad. there should be no new.

auto c = C(crap);

then classes and structs are more inter changeable.
July 11, 2008
Don Wrote:

> superdan wrote:
> > 4. warning - switch statement has no default
> > 
> > another example of a motherfuck. just require total coverage. in closed-set cases i routinely write anyway:
> > 
> > switch (crap)
> > {
> > case a: ...; break;
> > case b: ...; break;
> > default: assert(crap == c): ...; break;
> > }
> > 
> > again: vast majority of code already has a default. the minority just has to add a little code. make it an error.
> 
> Yup. Make it an error.

I agree with everything else, but this one I think shouldn't be an error or
warning (the implicit assert(0) is enough). This is because the vast
majority of switch statements I use (and many I see) are over enums, and
if every branch in the enumeration is covered, a pointless "default" will just
complicate code.

The "final switch" thing mentioned at the conference & now forgotten, OTOH, is a great idea for statically checking switch statements.
July 11, 2008
superdan Wrote:
> a / b is never larger than a (cept for signed/unsigned mixed shit).

a = -10; b = -5
July 11, 2008
Robert Fraser Wrote:

> Don Wrote:
> 
> > superdan wrote:
> > > 4. warning - switch statement has no default
> > > 
> > > another example of a motherfuck. just require total coverage. in closed-set cases i routinely write anyway:
> > > 
> > > switch (crap)
> > > {
> > > case a: ...; break;
> > > case b: ...; break;
> > > default: assert(crap == c): ...; break;
> > > }
> > > 
> > > again: vast majority of code already has a default. the minority just has to add a little code. make it an error.
> > 
> > Yup. Make it an error.
> 
> I agree with everything else, but this one I think shouldn't be an error or
> warning (the implicit assert(0) is enough). This is because the vast
> majority of switch statements I use (and many I see) are over enums, and
> if every branch in the enumeration is covered, a pointless "default" will just
> complicate code.

you are not disagreeing. switching over an enum is already closed if you mention all cases. the compiler knows that. it should indeed just throw an error if you have an out-of-range value that you forged from an int. but that's an uncommon case. don't make all pay for a rare bug.

> The "final switch" thing mentioned at the conference & now forgotten, OTOH, is a great idea for statically checking switch statements.

yarp i liked it too til i realized all switches should be final.
July 11, 2008
Robert Fraser Wrote:

> superdan Wrote:
> > a / b is never larger than a (cept for signed/unsigned mixed shit).
> 
> a = -10; b = -5

i got lazy. whenever i said "larger" i really meant "larger type". so in this case the correct sentence was; a / b never requires a larger type than the type of a.
July 11, 2008
On Thu, 10 Jul 2008 16:06:45 -0400, superdan wrote:

> byte a, b;
> byte c = a + b;

I think that compilers should never generate warnings in these cases. If you overflow in arithmetic operations of same types, it is at most runtime error issue. You should know how large values can be stored in basic types, and use large enough data type in the code.

Since explicit casting easily hides bugs, it should not be used overwhelmingly.

> 5. warning - statement is not reachable
> 
> this is a tad more messy. people routinely insert a premature return in there to check for stuff. it pisses me off when that won't compile.

That is very good example, why it would be good to have possibility to (temporarily) generate code even when it has warnings. That way the warning does not go anywhere and you still can debug your program.

> i discovered i could do this:
> 
> if (true) return crap;

Thanks! :)