## digitalmars.D - Re: Wish: Variable Not Used Warning

Era Scarecrow <rtcvb32 yahoo.com> writes:
``` Hmmh, if I would do something like that, I would do it like
this:

bool isPrime(int number, int[] /* primesList */)
{
bool prime = true;

static if(false)
{
// Partial implementation; should still be
// syntactically valid D
foreach(pnum; primesList) { ... }
}
else
{
for(int cnt = 2; ...) { ... }
}

return prime;
}

Closer to what i am meaning. Wouldn't it throw an error though that you have
foreach(pnum; primesList) where the primesList is commented out? course the
smart compiler will probably see it as 'don't compile this code' and treat it
as a large comment to the else.

I'll in the middle of my project, make sure all

openings/closings are good, and then compile the

never run but instead i use the errors and warnings

bugs and simple problems earlier, rather then do an

then trace all the bugs all at once.

That's exactly the same way I work with the code. I
and continuously compile to see, if there are warnings or
errors. If
there would be a situation like above, and I would be just
list scanning part but being still unsure if it works, I
an assert or similar to catch the program immediately if it
goes there;

bool isPrime(int number, int[] primeList)
{
if(primeList)
{
assert(false); // Don't go here at the moment
foreach(pnum; primeList) { ... }
}
else
{
for(int cnt; ...;) if(!(number%cnt)) return false;
return true;
}
}

The a reason i had the 'primesList = null;' it's so the functionality of
isPrime() could start to be used and implimented right away, checking for a
prime, since primesList is only to be used as a speedup later, the purpose of
the code is to check for if the number is a prime. If i wanted to use the
isPrime (before i got the other half implimented), i'd have to intentionally
pass a null, thereby removing intended purpose of it's existance later, Speed.

As the example, i could impliment all my code with primesList with an array
that is filled with an appropriate number of primes to give me the result for a
prime very fast, but if it isn't implimented, it still works. the way i had it.

assert(false); //automatically makes the function fail reguardless.

Doing it this way, i can only run it if i pass a null. perhaps 'static
if(false){...}' is better in this scenario as you said before. But i also
wanted to ensure i had my variable names spelling and connections working
right, even if the rest of the code wasn't ready just yet.

But anyway, if I would starting to make that part, the
build-stoppable
warnings about unused code and similar would not be a big
issue any more,
since I would not be executing the program until I get the
errors &
warnings away.

Agreed. Build code, get it to work quickly and easily. Then refactor out
un-needed parts, and remove as many warnings as possible without making it ugly
and only to get the compiler to shut up about said warning.

Static if is something like #if-#endif in C/C++, but since
it is in the
compiler, it knows all about the constants & types in
the code (unlike C
preprocessor) \o/

That's nice to know. I'll start using it where applicable.

Assume, that (a+b) is always smaller than 8, which causes
infinite loop.
The compiler is able to know that. If the programmer was
intentionally
making an infinite loop, why didn't he use
"for(;;)" or "while(true)"? If
the compiler gives an error, that the expression is always
true, I think
there are two possibilities:

1) The programmer was checking out how smart is the
compiler, by
expressing an infinite loop in a hard way; to get the code
compiled, he
should change it to regular "for(;;)" or
"while(true)".

I can mostly see that only in instances of those trying to make better
checkers by making it fail any way possible, or making sure the error comes up
on a later build. Either way, if ;(a+b) < 8; always evaluates to less than 8,
and there's no way to get a or b to go up or might change to become something
higher (or a break somewhere to get out of the loop); most likely something is
missing; unless they have some 'clever code' which, then becomes a pain to
debug later.

2) The programmer didn't notice, that the values he was
using are never
evaluated greater than the intended loop termination
condition. He re-
examines the code and probably finds something that he was
missing in the
first attempt (forgot to add some other value, forgot to
change the loop
termination condition, ...)

Win-win -situation, isn't that?

Only if he's actually warned about the infinate loop. would this warn you? (i
will check myself later)

int a,b;

for (;(a+b)<8;)
{
if (a>=0)
a++;
if (b<=0)
b--;
}
both a and b change. is it smart enough to know it should ALWAYS be 0? (or -1
for a brief time)

or...

{
//...somewhere in the code.
a++;
b-=a;
a=b;
}

something's changing constantly so we know there's a possible potential for an
eventual false statement somewhere.

Yes, right. Of course, compiler should not give any kind of
warning if
the loop is clearly intentionally made infinite, or if the
condition is

while(true) ...		// No error
if(true) ...		// No error

auto a=file.getSize("myfile.txt");	// ulong
...
while( a != -1) ...	// Error

In fact, I would change the default behavior of the
compiler so that it
uses all warnings and regards them as errors. For testing
out incomplete
code, a "--cmon-relax" flag could be used :)

Sounds good to me. It just seems like there's a delicate balance where all
warnings are errors, and not all warnings can be delt with without some type of
ugly work-around (in some situations), where a warning would be better than an
error.

I honestly believe that unused variables shouldn't be an error; at least until
i've finished building a working version of the function. Then start
refactoring and removing un-needed parts. Once ready for release, all warnings
that can be removed, are treated as errors.

Last thing i personally want to do is to put in variables i know i need, and
then have to comment them out just to get the compiler to be quiet because they
aren't used, just so i can confirm some basic logic right before working on the
block of code that would have held the variables i just commented out. The
annoyance of jumping back and forth when i could have just left them alone to
begin with is mostly where i'm going towards. production code and final code?
Variables that aren't used should be errors.

```
Jul 10 2008
Markus Koskimies <markus reaaliaika.net> writes:
```On Thu, 10 Jul 2008 15:05:30 -0700, Era Scarecrow wrote:

Hmmh, if I would do something like that, I would do it like this:

bool isPrime(int number, int[] /* primesList */) {
bool prime = true;

static if(false)
{
// Partial implementation; should still be //

foreach(pnum; primesList) { ... }
}
else
{
for(int cnt = 2; ...) { ... }
}

return prime;
}

Closer to what i am meaning. Wouldn't it throw an error though that you
have foreach(pnum; primesList) where the primesList is commented out?

The block inside of static if is only syntactically checked. It does not
have to have valid references to variables, classes or something like
that.

Like said, it is just like #if...#endif, with the exception that

(1) static if knows all about the code around it (i.e. you can use e.g.
sizes of some aliased types in expression)

(2) static if allos only syntactically correct blocks inside of it (that
block is parsed, but anything else is not made for it)

course the smart compiler will probably see it as 'don't compile this
code' and treat it as a large comment to the else.

Smart compiler regocnizes, when the attempt is intentional and when it is
more likely spurious. Like side, there is a big differece between making
infinite loops like:

1) while(true) { ... }
2) while(-4 < -2) { ... }

..Or outcommenting;

1) if(false) { ...}
2) if(-1 > 0) { ... }

(you catched the point? If you didn't, consider that the compiler has
evaluated a complex expression to correspond the second examples)

The a reason i had the 'primesList = null;' it's so the functionality
of isPrime() could start to be used and implimented right away,
checking for a prime, since primesList is only to be used as a speedup
later, the purpose of the code is to check for if the number is a
prime.

Yes, I understood that. There's plenty of possibilities to do that even
with "full C++-like warnings" (D has only ridiculously small set of that)
if warnings are treated as errors.

assert(false); //automatically makes the function fail reguardless.

Doing it this way, i can only run it if i pass a null.

Yes, true, but if it is not working, why do you want it to go there? That
was just an example to enable code, and to guard it not to be executed
while testing other parts.

[...]
Agreed. Build code, get it to work quickly and easily. Then refactor
out un-needed parts, and remove as many warnings as possible without
making it ugly and only to get the compiler to shut up about said
warning.

Yes, exactly me!

Assume, that (a+b) is always smaller than 8, which causes infinite
loop.
The compiler is able to know that. If the programmer was intentionally
making an infinite loop, why didn't he use "for(;;)" or "while(true)"?
If
the compiler gives an error, that the expression is always true, I
think
there are two possibilities:

1) The programmer was checking out how smart is the compiler, by
expressing an infinite loop in a hard way; to get the code compiled, he
should change it to regular "for(;;)" or "while(true)".

I can mostly see that only in instances of those trying to make better
checkers by making it fail any way possible, or making sure the error
comes up on a later build. Either way, if ;(a+b) < 8; always evaluates
to less than 8, and there's no way to get a or b to go up or might
change to become something higher (or a break somewhere to get out of
the loop); most likely something is missing; unless they have some
'clever code' which, then becomes a pain to debug later.

I completely agree!

2) The programmer didn't notice, that the values he was using are never
evaluated greater than the intended loop termination condition. He re-
examines the code and probably finds something that he was missing in
the
first attempt (forgot to add some other value, forgot to change the
loop
termination condition, ...)

Win-win -situation, isn't that?

Only if he's actually warned about the infinate loop.

In the case that compiler has produced an infinite loop, by optimizing
away unnecassary parts, and it recognizes that the source indicates
something else (i.e. not "while(true)"), would it be polite to tell that
to the programmer?

If the compiler is dumb enough not to optimize expressions like:

while(-2 < -1) { ... }

...Then there is of course no need to produce warning (i.e. if the
compiler generates code, that loads -2 to one register and -1 one
register and really performs cmp between those).

int a,b;

for (;(a+b)<8;)
{
if (a>=0)
a++;
if (b<=0)
b--;
}
both a and b change. is it smart enough to know it should ALWAYS be 0?
(or -1 for a brief time)

Oh my god. It would take me a while to really analyze that kind of code.
If that kind of loop would appear when I'm keeping review, I would put
the programmer to make some simplifications to the loop...

In any case, quickly analyzed, that would easily produce an infinite
loop. a is growing all the time it is greater than zero, while b is
decreasing all the time it is less zero. Likely outputs would be;

1) a < 0 ==> if b < 0, almost infinite, otherwise if (a+b) >= 8 it would
not take a round,

2) a > 0 ==> if b < 0, infinite loop; a and b would compensate each other

3) Many undeterministic behaviors; from 0 to 8 rounds, and if more than
8, would lead to almost infinite

or...

{
//...somewhere in the code.
a++;
b-=a;
a=b;
}

The behaviour would be hugely dependent on the inital values of a and b.
Many non-deterministic results, and because of a-=b clause it could lead
to infinite loops.

something's changing constantly so we know there's a possible potential
for an eventual false statement somewhere.

Compilers cannot regularly catch the things you presented above. They
catch much more simple things, most likely caused because of you forgot
something.

Last thing i personally want to do is to put in variables i know i
need, and then have to comment them out just to get the compiler to be
quiet because they aren't used, just so i can confirm some basic logic
right before working on the block of code that would have held the
variables i just commented out. The annoyance of jumping back and forth
when i could have just left them alone to begin with is mostly where
i'm going towards. production code and final code? Variables that
aren't used should be errors.

Like said, I have used so much "g++ -Wall" and "lint" by making my salary
in private companies (which regularly gives a shit to fancy things, it
just need to work and you are forced to do code like being in army; no
own will, suggestions may be considered in next year), that I have used
to sketch code so that it does not generate warnings. My bad, indeed,
although I'm not the biggest fan of completely freedom of making code
(i.e. good practices).
```
Jul 10 2008