Wish: Variable Not Used Warning

Era Scarecrow rtcvb32 at yahoo.com
Thu Jul 10 15:05:30 PDT 2008


> 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
> my block
> >  openings/closings are good, and then compile the
> code, which i will
> >  never run but instead i use the errors and warnings
> to find certain
> >  bugs and simple problems earlier, rather then do an
> entire file and
> >  then trace all the bugs all at once.
> 
> That's exactly the same way I work with the code. I
> keep adding blocks 
> and continuously compile to see, if there are warnings or
> errors. If 
> there would be a situation like above, and I would be just
> added that 
> list scanning part but being still unsure if it works, I
> would add there 
> 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;
}

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.


> 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 
> clearly intentionally made constant:
> 
> 	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.


      



More information about the Digitalmars-d mailing list