Wish: Variable Not Used Warning

Markus Koskimies markus at reaaliaika.net
Thu Jul 10 22:00:33 PDT 2008


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 // 
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?

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.

> not sure if the compiler will be quiet about this either, but logically
> 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).



More information about the Digitalmars-d mailing list