www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Unused variables and bugs

reply "bearophile" <bearophileHUGS lycos.com> writes:
Apparently there is evidence that unused variables in C-like 
languages correlate with bugs:

https://kev.inburke.com/slides/errors/#error-correlations

One problem with ruling out some classes of unused variables 
(like unused function arguments, unused private module-level 
variables, unused function-local variables, and so on) is that 
when you are writing code you sometimes add some unused 
variables, that you usually will use or remove later.

So you usually don't want an error or warning for unused 
variables when you are writing code, but later there is a moment 
when you probably want to clean up your code and remove any 
unused variable to make the code more clean and tight.

A simple solution in C-languages is to add a compiler switch that 
allows to disallow or allow the unused variables according to the 
phase of your working on the code. But compiler switch 
proliferation can be a problem (unless you use an IDE, that 
offers you a button to enable/disable such tests).

Another solution is to leave such tests out of the core compiler, 
and put them in a lint tool that you run when you think your code 
is in good shape.

Bye,
bearophile
Aug 22 2014
next sibling parent reply "Brian Schott" <briancschott gmail.com> writes:
On Friday, 22 August 2014 at 19:07:24 UTC, bearophile wrote:
 Another solution is to leave such tests out of the core 
 compiler, and put them in a lint tool that you run when you 
 think your code is in good shape.
https://github.com/Hackerpilot/Dscanner The unused variable and unused parameter checks have existed since May. As far as I know it only gives false positives if mixin statements are present.
Aug 22 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
Brian Schott:

 The unused variable and unused parameter checks have existed 
 since May. As far as I know it only gives false positives if 
 mixin statements are present.
Another interesting feature is similar to -Wsuggest-final-types and -Wsuggest-final-methods. They give warnings when there is a method or whole class that can be tagged with "final". This allows to avoid virtual methods. This in D is even more important than C++ because of the virtual on the default of D, that was widely discussed and at the end never fixed. Bye, bearophile
Aug 22 2014
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/22/2014 09:07 PM, bearophile wrote:
 Apparently there is evidence that unused variables in C-like languages
 correlate with bugs:

 https://kev.inburke.com/slides/errors/#error-correlations
 ...
http://xkcd.com/552/
Aug 22 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Timon Gehr:

 http://xkcd.com/552/
What better alternative do you suggest in practice? The only better solution I remember that was used for a language design is the ":" added to Python after some controlled experiments done on users. Relying on experimental correlations (if the analysis is done well) seems sometimes better than the usual beers&intuition-based ways most language features are chosen and designed :-) Currently a group of people are trying to design a language pushing to the extreme the idea of design by committee, it's future a peer reviewed language meant to be used for scientific programming. I've taken a look at its syntax and I was not happy with the current work in progress. Bye, bearophile
Aug 22 2014
next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
On 8/22/14, 6:46 PM, bearophile wrote:
 Currently a group of people are trying to design a language pushing to
 the extreme the idea of design by committee, it's future a peer reviewed
 language meant to be used for scientific programming. I've taken a look
 at its syntax and I was not happy with the current work in progress.
What language is that?
Aug 22 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
Ary Borenszweig:

 What language is that?
I don't remember its name, of course. I have just scanned the last few months of the LambdaTheUltimate blog without success. Bye, bearophile
Aug 22 2014
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/22/2014 11:46 PM, bearophile wrote:
 Timon Gehr:

 http://xkcd.com/552/
...
My point is just that this correlation is not a strong data point supporting putting effort into elimination of unused variables. It is possible that all this will accomplish is that unused variables will no longer be an indicator of code quality.
 What better alternative do you suggest in practice?
Write the code carefully and convince yourself and possibly others that it is correct. Time is much more effectively spent attempting to improve code quality rather than attempting to improve metrics that have been shown to correlate with code quality in the past. Of course, the lint may prove useful during such endeavours as well; it's just the interpretation of the lint results that should be different. Given that one believes in the accuracy/generalizability/etc of the data from the OT, and if the lint gives many warnings, then this should indicate that maybe one should go over the surrounding code again carefully, not that one should just quickly fix the specific issues that the lint highlighted as you seemed to suggest in the OT. The correlation only indicates that poor code tends to have more unused variables. If one eliminates unused variables just for the sake of eliminating unused variables, code quality will most likely not magically increase.
 The only better
 solution I remember that was used for a language design is the ":" added
 to Python after some controlled experiments done on users.

 Relying on experimental correlations (if the analysis is done well)
The experiment/analysis is done well if it would likely disprove a hypothesis that further reasoning will be based on if it was wrong, but hasn't done so.
 seems sometimes better than the usual beers&intuition-based
My own intuition is that 'no unused variables' and code quality might have a common cause in a setting where unused variables are not artificially eliminated, but this might be off as well. If reasoning is to be based on experiments, the experiments should be cleverly targeted at the right hypothesis. It does not suffice to say that past experiments gave results that were consistent with one's intuitive interpretation of reality in order to support this interpretation if the experimental results would also support a variety of other interpretations just the same way.
 ways most language features are chosen and designed :-)
Your source apparently also claims that code that has many comments has more errors: https://kev.inburke.com/slides/errors/#error-correlations-2 I.e. to increase code quality one should delete comments?
Aug 22 2014
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/23/2014 01:32 AM, Timon Gehr wrote:
 you seemed to suggest in the OT.
OP
Aug 22 2014
prev sibling parent reply "Brian Schott" <briancschott gmail.com> writes:
On Friday, 22 August 2014 at 23:32:54 UTC, Timon Gehr wrote:
 The correlation only indicates that poor code tends to have 
 more unused variables. If one eliminates unused variables just 
 for the sake of eliminating unused variables, code quality will 
 most likely not magically increase.
I would argue that eliminating unused variables always improves code quality. If you have unused variables you are wasting the compilers time, confusing anybody who reads your code, and possibly making the resulting binary less efficient. Nobody is arguing that it is the mythical vampire-slaying silver bullet. (At least I hope not)
Aug 22 2014
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/23/2014 02:03 AM, Brian Schott wrote:
 On Friday, 22 August 2014 at 23:32:54 UTC, Timon Gehr wrote:
 The correlation only indicates that poor code tends to have more
 unused variables. If one eliminates unused variables just for the sake
 of eliminating unused variables, code quality will most likely not
 magically increase.
I would argue that eliminating unused variables always improves code quality. If you have unused variables you are wasting the compilers time, confusing anybody who reads your code, and possibly making the resulting binary less efficient. Nobody is arguing that it is the mythical vampire-slaying silver bullet. (At least I hope not)
Yah, code quality wasn't specific enough. I meant code correctness.
Aug 22 2014
prev sibling parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Fri, 22 Aug 2014 21:46:44 +0000
bearophile via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 What better alternative do you suggest in practice?
don't declare unused variables. really, this is extremely easy. my 15+ years of expirience in writing projects of different scale shows that good decomposition, code architecture and scopes allows to not declare variable "just in case we'll need it later". there is no more punch-cards and teletypes, we have good text editors and we can easily add any necessary declaration just when we need it. and when compiler complains about unused variable, this indicates that i either forgot to code something or forgot to do a cleanup after previous code version.
Aug 22 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Saturday, 23 August 2014 at 02:48:15 UTC, ketmar via
Digitalmars-d wrote:
 don't declare unused variables. really, this is extremely easy. 
 my 15+
 years of expirience in writing projects of different scale
What about: - versioning - debugging (commenting out debugging code) - virtual functions - future-proof function signatures Of course the common way to deal with it in C is to tell the compiler that it is intentional by casting to void: (void) argc; (void) argv;
Aug 22 2014
parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 23 Aug 2014 03:50:13 +0000
via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 - versioning
refactor it, so that shared code goes to separate functions. nested functions especially helpful here. i'm used to this GCC extension.
 - debugging (commenting out debugging code)
why comment it out? if (debug_enabled) is fine and can help when software fails.
 - virtual functions
they are either abstract or just comment out unused argument names.
 - future-proof function signatures
but why? plan your API. if you need to extend it -- add new API calls.
Aug 22 2014
next sibling parent reply "Ola Fosheim Gr" <ola.fosheim.grostad+dlang gmail.com> writes:
On Saturday, 23 August 2014 at 04:07:58 UTC, ketmar via 
Digitalmars-d wrote:
 On Sat, 23 Aug 2014 03:50:13 +0000
 via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 - versioning
refactor it, so that shared code goes to separate functions. nested functions especially helpful here. i'm used to this GCC extension.
Won't work. Different versions might need extra parameters, but you want the same interface. Like one version might need manual calibration.
 - debugging (commenting out debugging code)
why comment it out? if (debug_enabled) is fine and can help when software fails.
To avoid visual clutter. To be able to span syntactical boundaries. To take advantage of hiding in editors.
 - virtual functions
they are either abstract or just comment out unused argument names.
No, unused in superclasses, used in subclasses.
 - future-proof function signatures
but why? plan your API. if you need to extend it -- add new API calls.
And rewrite all use locations? That sounds like not planning...
Aug 22 2014
parent "Brendan Zabarauskas" <bjzaba yahoo.com.au> writes:
I use Rust a reasonable amount, and the 'unused variable', 
'unused field' and 'unused item' family of lints help a great 
deal in picking up mistakes early, especially when refactoring. 
Don't ask me to cite specific examples though - because they are 
enabled by default the issues are usually picked up and addressed 
early.

Note that in order not to make the the lint more bearable, 
underscore-prefixed identifiers are ignored and you can also 
disable any lint can be disabled on an item-by-item basis using 
an attribute (although in practice the latter option is rarely 
used). I do think without those options it would be a massive 
pain. The underscore thing might not be an option for D though - 
do preceding underscores have a specific meaning in the 
prevailing D coding style?
Aug 24 2014
prev sibling parent reply "Idan Arye" <GenericNPC gmail.com> writes:
On Saturday, 23 August 2014 at 04:07:58 UTC, ketmar via 
Digitalmars-d wrote:
 On Sat, 23 Aug 2014 03:50:13 +0000
 via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 - versioning
refactor it, so that shared code goes to separate functions. nested functions especially helpful here. i'm used to this GCC extension.
 - debugging (commenting out debugging code)
why comment it out? if (debug_enabled) is fine and can help when software fails.
 - virtual functions
they are either abstract or just comment out unused argument names.
 - future-proof function signatures
but why? plan your API. if you need to extend it -- add new API calls.
How about unused arguments in lambda expressions? import std.stdio; void foo(int delegate(int) dlg){ writeln(dlg(12)); } void main(){ foo((x) => x+1); // No problem here foo((x) => 42); // Unused argument //foo(() => 42); // Error //foo(auto) => 42); // Error //We have to use: foo((int) => 42); } Since `auto` doesn't work in lambda expressions, we have to give up on type inference for arguments we are not even using!
Aug 23 2014
parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 23 Aug 2014 15:48:03 +0000
Idan Arye via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 How about unused arguments in lambda expressions?
also, make compiler accept 'auto' in lambdas. i'm sure it should. and it should accept 'auto' in foreach(). it should also allow foreach like this: foreach (auto, auto; foo). alas, seems that nobody is interested in this small improvements, and i myself neither know fronted internals enough, nor want to write this anyway, 'cause patches will just rot in bugzilla.
Aug 23 2014
parent reply "Idan Arye" <GenericNPC gmail.com> writes:
On Sunday, 24 August 2014 at 02:23:11 UTC, ketmar via 
Digitalmars-d wrote:
 On Sat, 23 Aug 2014 15:48:03 +0000
 Idan Arye via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 How about unused arguments in lambda expressions?
also, make compiler accept 'auto' in lambdas. i'm sure it should. and it should accept 'auto' in foreach(). it should also allow foreach like this: foreach (auto, auto; foo). alas, seems that nobody is interested in this small improvements, and i myself neither know fronted internals enough, nor want to write this anyway, 'cause patches will just rot in bugzilla.
Currenly foreach does not accept type-without-argument - `foreach(int; [1,2,3])` is a compiler error - so that's much bigger a change than adding argument-less type inference for lambdas.
Aug 24 2014
parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 24 Aug 2014 19:39:31 +0000
Idan Arye via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 Currenly foreach does not accept type-without-argument -=20
 `foreach(int; [1,2,3])` is a compiler error - so that's much=20
 bigger a change than adding argument-less type inference for=20
 lambdas.
ah, it's almost the same. easy deal. i updated my 'foreach patch', and now it happily accepts `foreach(int; [1,2,3])`. https://issues.dlang.org/show_bug.cgi?id=3D12488
Aug 24 2014