www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Super Lint

reply Walter Bright <newshound digitalmars.com> writes:
I've been interested in various ideas for static checking for common bug 
patterns for D. For example:

	for (int i = 0; i < 10; i++)
	{	foo();
		break;
	}

would be flagged as a suspicious use of break. Are there any legitimate 
uses of break in this manner? Any thoughts and ideas in this direction?
Sep 20 2006
next sibling parent reply Pragma <ericanderton yahoo.removeme.com> writes:
Walter Bright wrote:
 I've been interested in various ideas for static checking for common bug 
 patterns for D. For example:
 
     for (int i = 0; i < 10; i++)
     {    foo();
         break;
     }
 
 would be flagged as a suspicious use of break. Are there any legitimate 
 uses of break in this manner? Any thoughts and ideas in this direction?

Well, one could throw from within foo(), but that would still abort the loop on the first pass. Nope, there's no legitimate use I can think of. Are you considering making a lint tool for D? -- - EricAnderton at yahoo
Sep 20 2006
next sibling parent J Duncan <jtd514 nospam.ameritech.net> writes:
Pragma wrote:
 Walter Bright wrote:
 I've been interested in various ideas for static checking for common 
 bug patterns for D. For example:

     for (int i = 0; i < 10; i++)
     {    foo();
         break;
     }

 would be flagged as a suspicious use of break. Are there any 
 legitimate uses of break in this manner? Any thoughts and ideas in 
 this direction?

Well, one could throw from within foo(), but that would still abort the loop on the first pass. Nope, there's no legitimate use I can think of. Are you considering making a lint tool for D?

Sep 20 2006
prev sibling parent reply Walter Bright <newshound digitalmars.com> writes:
Pragma wrote:
 Walter Bright wrote:
 I've been interested in various ideas for static checking for common 
 bug patterns for D. For example:

     for (int i = 0; i < 10; i++)
     {    foo();
         break;
     }

 would be flagged as a suspicious use of break. Are there any 
 legitimate uses of break in this manner? Any thoughts and ideas in 
 this direction?

Well, one could throw from within foo(), but that would still abort the loop on the first pass. Nope, there's no legitimate use I can think of. Are you considering making a lint tool for D?

Not exactly. Lint finds things that might be bugs, but my experience with Lint is it flags legitimate code patterns as bugs. I'd prefer to do things that are out and out bugs, like the example above.
Sep 20 2006
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Walter Bright wrote:
 Pragma wrote:
 Walter Bright wrote:
 I've been interested in various ideas for static checking for common 
 bug patterns for D. For example:

     for (int i = 0; i < 10; i++)
     {    foo();
         break;
     }

 would be flagged as a suspicious use of break. Are there any 
 legitimate uses of break in this manner? Any thoughts and ideas in 
 this direction?

Well, one could throw from within foo(), but that would still abort the loop on the first pass. Nope, there's no legitimate use I can think of. Are you considering making a lint tool for D?

Not exactly. Lint finds things that might be bugs, but my experience with Lint is it flags legitimate code patterns as bugs. I'd prefer to do things that are out and out bugs, like the example above.

But is it safe do declare the above example as a bug? Maybe that break is placed there to see what just one pass of the loop does (maybe for debugging purposes).
Sep 20 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
Ivan Senji wrote:
 Walter Bright wrote:
 Pragma wrote:
 Walter Bright wrote:
 I've been interested in various ideas for static checking for common 
 bug patterns for D. For example:

     for (int i = 0; i < 10; i++)
     {    foo();
         break;
     }

 would be flagged as a suspicious use of break.




 But is it safe do declare the above example as a bug? Maybe that break 
 is placed there to see what just one pass of the loop does (maybe for 
 debugging purposes).

That certainly is the question. I don't think I'd want to see such code in released source, but: 1) is it legitimate for debug/test code? 2) can it come about as the side effect of some other coding pattern? 3) if it is made illegal, is that going to be a bigger problem than it solves? 4) does it really solve a problem? For example, it could happen with (example found on the internet): for (int i = 0; i < 10; i++) { if (condition) action(); break; } where the user forgot to put { } around the else clause. It's sort of like how: for (int i = 0; i < 10; i++); { ... } is illegal in D (note the ; after the closing parenthesis). I've known people to spend many hours trying to track down this nearly invisible bug.
Sep 20 2006
next sibling parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Walter Bright wrote:
 Ivan Senji wrote:
 Walter Bright wrote:
 Pragma wrote:
 Walter Bright wrote:
 I've been interested in various ideas for static checking for 
 common bug patterns for D. For example:

     for (int i = 0; i < 10; i++)
     {    foo();
         break;
     }

 would be flagged as a suspicious use of break.




 But is it safe do declare the above example as a bug? Maybe that break 
 is placed there to see what just one pass of the loop does (maybe for 
 debugging purposes).

That certainly is the question. I don't think I'd want to see such code in released source, but: 1) is it legitimate for debug/test code?

Most legal code will probably be legitimate for /some/ debug/test code. The question is, would you want to run a tool like this on such code? (I'm presuming this will be an exteral tool) Besides, if debug code like this is found, I'd hope a tool like this would alert me to the fact I forgot to remove some debugging code.
 2) can it come about as the side effect of some other coding pattern?

Probably not as written, but how about this variant: for (int i = 0; i < 10; i++) { if (foo()) continue; break; } Granted, it should be relatively simple to detect a continue statement that has an effect on the loop since it can't hide in function calls. I can't think of any other reason to use an unconditional break except the above-mentioned debug scenario.
 3) if it is made illegal, is that going to be a bigger problem than it 
 solves?

Illegal or just flagged by this "super lint"? I've never used lint, but my understanding is that it's an external tool that checks for common errors (that are still legal code). As such, it can't actually make things illegal, just advise against them when found.
 4) does it really solve a problem?
 
 For example, it could happen with (example found on the internet):
 
     for (int i = 0; i < 10; i++)
     {
         if (condition)
             action();
             break;
     }
 
 where the user forgot to put { } around the else clause. It's sort of 
 like how:
 
     for (int i = 0; i < 10; i++);
     {
         ...
     }
 
 is illegal in D (note the ; after the closing parenthesis). I've known 
 people to spend many hours trying to track down this nearly invisible bug.

This is a tougher question. Though it may be nice to have it warn about multiple indented statements (without {}s) after a conditional or loop statement, that might be a more common problem than unconditional breaks. Of course, that would mean it has to pay attention to formatting, which might complicate things.
Sep 20 2006
prev sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
Walter Bright wrote:
 Ivan Senji wrote:
 But is it safe do declare the above example as a bug? Maybe that break 
 is placed there to see what just one pass of the loop does (maybe for 
 debugging purposes).

That certainly is the question. I don't think I'd want to see such code in released source, but: 1) is it legitimate for debug/test code? 2) can it come about as the side effect of some other coding pattern? 3) if it is made illegal, is that going to be a bigger problem than it solves? 4) does it really solve a problem? For example, it could happen with (example found on the internet): for (int i = 0; i < 10; i++) { if (condition) action(); break; } where the user forgot to put { } around the else clause. It's sort of like how: for (int i = 0; i < 10; i++); { ... } is illegal in D (note the ; after the closing parenthesis). I've known people to spend many hours trying to track down this nearly invisible bug.

I think this a great idea. The for loop example is one of the so-called incremental improvements in D that saved me quite some time vs C++. I almost forgot how annoying it is to spend time on hunting for bugs that are just typo's. It's very reasonable for such a tool imho to demand debug code that is otherwise a bug be written with debug version statements, thus I don't see the debug argument as a con.
Sep 20 2006
prev sibling next sibling parent reply xs0 <xs0 xs0.com> writes:
Walter Bright wrote:
 I've been interested in various ideas for static checking for common bug 
 patterns for D. For example:
 
     for (int i = 0; i < 10; i++)
     {    foo();
         break;
     }
 
 would be flagged as a suspicious use of break. Are there any legitimate 
 uses of break in this manner? Any thoughts and ideas in this direction?

Well, I occasionally write something similar: for (int i = 0; i < max_retries; i++) { try { foo(); } catch (Exception e) { continue; } break; } I'm not sure if it's related, though (does the continue make Lint shut up?). I have no "legitimate" ideas about breaking unconditionally, though, except for debugging. xs0
Sep 20 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
xs0 wrote:
 Walter Bright wrote:
 I've been interested in various ideas for static checking for common 
 bug patterns for D. For example:

     for (int i = 0; i < 10; i++)
     {    foo();
         break;
     }

 would be flagged as a suspicious use of break. Are there any 
 legitimate uses of break in this manner? Any thoughts and ideas in 
 this direction?

Well, I occasionally write something similar: for (int i = 0; i < max_retries; i++) { try { foo(); } catch (Exception e) { continue; } break; }

Hmm. That does look like a quite reasonable use case.
Sep 20 2006
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Walter Bright wrote:
 xs0 wrote:
 Walter Bright wrote:
 I've been interested in various ideas for static checking for common 
 bug patterns for D. For example:

     for (int i = 0; i < 10; i++)
     {    foo();
         break;
     }

 would be flagged as a suspicious use of break. Are there any 
 legitimate uses of break in this manner? Any thoughts and ideas in 
 this direction?

Well, I occasionally write something similar: for (int i = 0; i < max_retries; i++) { try { foo(); } catch (Exception e) { continue; } break; }

Hmm. That does look like a quite reasonable use case.

It also looks like a quite /detectable/ use case. Just look for a continue statement somewhere in that loop (and outside any nested ones).
Sep 20 2006
parent Kevin Bealer <kevinbealer gmail.com> writes:
Frits van Bommel wrote:
 Walter Bright wrote:
 xs0 wrote:
 Walter Bright wrote:
 I've been interested in various ideas for static checking for common 
 bug patterns for D. For example:

     for (int i = 0; i < 10; i++)
     {    foo();
         break;
     }

 would be flagged as a suspicious use of break. Are there any 
 legitimate uses of break in this manner? Any thoughts and ideas in 
 this direction?

Well, I occasionally write something similar: for (int i = 0; i < max_retries; i++) { try { foo(); } catch (Exception e) { continue; } break; }

Hmm. That does look like a quite reasonable use case.

It also looks like a quite /detectable/ use case. Just look for a continue statement somewhere in that loop (and outside any nested ones).

Couldn't this be simplified to: for(...) { try { foo(); break; } catch(...) } } Though I guess this doesn't necessarily mean the first form is lint-error-worthy. Kevin
Sep 23 2006
prev sibling next sibling parent reply Derek Parnell <derek psyc.ward> writes:
On Wed, 20 Sep 2006 12:09:28 -0700, Walter Bright wrote:

 I've been interested in various ideas for static checking for common bug 
 patterns for D. For example:
 
 	for (int i = 0; i < 10; i++)
 	{	foo();
 		break;
 	}
 
 would be flagged as a suspicious use of break. Are there any legitimate 
 uses of break in this manner? Any thoughts and ideas in this direction?

I have used this type of thing as a temporary debugging aid. But I suppose I could use ... for (int i = 0; i < 10; i++) { foo(); debug break; } -- Derek Parnell Melbourne, Australia "Down with mediocrity!"
Sep 20 2006
parent =?ISO-8859-1?Q?Lu=EDs_Marques?= <luismarques+spam gmail.com> writes:
Derek Parnell wrote:
 I have used this type of thing as a temporary debugging aid. But I suppose
 I could use ...
 
  	for (int i = 0; i < 10; i++)
  	{	foo();
  		debug break;
  	}

Also you could not run the lint tool on the temporary debugging code. Like Frits said, it's nice to have a tool that detects forgotten debugging code, so if the tool trips on common debugging aids that might even be useful.
Sep 20 2006
prev sibling parent Miles <_______ _______.____> writes:
Walter Bright wrote:
 I've been interested in various ideas for static checking for common bug
 patterns for D. For example:
 
     for (int i = 0; i < 10; i++)
     {    foo();
         break;
     }
 
 would be flagged as a suspicious use of break. Are there any legitimate
 uses of break in this manner? Any thoughts and ideas in this direction?

Yes, there are. Once I had this problem: Obj *v[n], **p; for (p = v; *p != NULL; p++) { do_something(*p); if (condition1(*p)) continue; /* failed */ do_something_else(*p); if (condition2(*p)) continue; /* failed */ ... do_the_last_thing(*p); if (conditionN(*p)) continue; /* failed */ break; /* good! */ } if (*p != NULL) return *p; else throw NoSuitableIndividual; It was an AI application. This function returns the first Obj in array 'v' which survives all 17 conditions of a natural selection process. Of course, the last condition could be rewritten as something like: ... if (!conditionN(*p)) return *p; /* good! */ } ... But it is just an example.
Sep 20 2006