Wish: Variable Not Used Warning

Markus Koskimies markus at reaaliaika.net
Thu Jul 10 13:18:02 PDT 2008


On Thu, 10 Jul 2008 10:10:49 -0700, Era Scarecrow wrote:

> //returns true/flase if a prime.
> bool isPrime(int number, int[] primesList) {
> 	int cnt;
> 	bool prime = true;
> 
> 	primesList = null;	//disable for now.
>                               //When fully implimented, remove
> 
> 	if (primesList)	//gives an error since it never executes,
>                       //but logic is there. 
>       {
> 		foreach (pnum; primesList)
> 		{
> 		//finish later
> 		}
> 
> 	}
> 	else
> 		for (cnt = 2; cnt < number; cnt++)
> 			if (number % cnt == 0)
> 				prime=false;
> 
> 
> 	return prime;
> }

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;
}

In fact, I wouldn't even put that list scanning part there, if I'm 
working with the loop there. Even when I'm just sketching code, I try to 
avoid large numbers of unused and incomplete parts there; I mainly sketch 
the interface, and start from core parts to put things together.

>  Being partially implimented, i don't really want to comment out large
>  areas of my code, since i want to know if i wrote it wrong, or right.

Yeah, I don't like large out-commented blocks either. But I normally 
write the code in pieces, so at that case I would first implement that 
loop and only slightly - if at all - touch to that primesList part.

This easily goes to a discussion about how to sketch code, and I try to 
avoid that. I still see no use to allow unused vars & members and dead 
code, since they are regularly easily work-arounded in D during sketching 
phase, and you don't want them to be there at the end.

>  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;
	}	
}

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.

>  Or am i doing it wrong?

I don't think so, but I feel that warnings and code sketching are not 
mutually exclusive things :D

Anyway, I surfed in the net and found some writings about warnings and D. 
I'll quote here two things;

Walter Bright about Redundancy in Programming Languages: "You can get a 
feel for where redundancy in a language is lacking by looking at warning 
diagnostics the compiler implementors tend to add over time. For the 
designer of a new language, common warnings are a rich source of 
inspiration for improvements."

http://dobbscodetalk.com/index.php?option=com_myblog&show=Redundancy-in-
Programming-Languages.html&Itemid=29

D 2.0 Overview, "Who D is Not For"; "Language purists. D is a practical 
language, and each feature of it is evaluated in that light, rather than 
by an ideal."

http://www.digitalmars.com/d/2.0/overview.html

Warnings may indicate imperfectness in language design, but from 
practical point of view I would accept that and add all practical 
warnings, although my aim would get rid of them in the future.

>  Still learning D, i've seen references of static if's but i haven't
>  read enough on it yet.

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/

>> if you have an expression:
>> 
>> 	for(...; (a + b) < 8; ...) { ... }
>> 
>> ...if the compiler recognizes, that the condition cannot never be
>> anything else than true or false, do you think it is intentional?
> 
>  if it was truely intentional, then wouldn't you do..?

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)".

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?

>  if it wasn't intentional, then you were trying to actually check for
>  something.

Exactly. That's why I like error-like warnings, that won't pass through 
suspicious parts.

>> > while(1)    //always true
>> > {
>> >     if (someCondition){
>> >         break;
>> >     }
>> > }
>> 
>> The same hold here; "while(true)",
>> "for(;;)" are intentionally written to be infinite loops. I regularly
>> define in C/C++:
> 
> those are truely intentional, a contition should actually have a chance
> to change and be true/false at different steps, correct?

>From this point on, I don't any more use the word warning. Instead I use 
the word error. I'm not speaking about "Variable Not Used *Warning*", but 
instead of "Variable Not Used *Error*" and "Unreachable Statement 
*Error*".

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 :)




More information about the Digitalmars-d mailing list