digitalmars.D - Super Lint
↑ ↓ ← → 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?
↑ ↓ ← → 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
↑ ↓ ← → 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?
↑ ↓ ← → 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.
↑ ↓ ← → 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).
↑ ↓ ← → 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.
↑ ↓ ← → 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.
↑ ↓ ← → 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.
↑ ↓ ← → 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
↑ ↓ ← → 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.
↑ ↓ ← → 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).
↑ ↓ ← → 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
↑ ↓ ← → 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!"
↑ ↓ ← → =?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.
↑ ↓ ← → 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.
|