July 09, 2008
Nick Sabalausky wrote:

> Like I've said, compiler warnings are essentialy a built-in lint tool.

Finally the contradiction seems to show up: if lint is a tool in its own right, then one must have strong arguments to incorporate it into any other tool.

In the paralell posting Walter remarks but not emphasizes that compilers have more goals, than enabling the evaluation of sources, on which your OP concentrates. Building large software systems and migrating some application source to another architecture are in the duties of compilers.

For at least huge parts of these latter tasks a reevaluation of some static aspects of semantics of the application is useless but time consuming. In addition and by definition lint tools are not capable of doing more than this.

This is the central point: lint tools are only capable of informing about possible bugs. If a warning emitted by a lint tool would be a sure hint for a bug in the program, then the compiler should have emitted an error.

Thus there should be no need to incorporate any lint tool into any compiler. I am ready to read your counter arguments.

-manfred

-- 
Maybe some knowledge of some types of disagreeing and their relation can turn out to be useful: http://blog.createdebate.com/2008/04/07/writing-strong-arguments/
July 09, 2008
Here are some horrid examples from my own code which, to please the client, had to compile with all warnings on for MSVC:

---
  p = NULL;  // suppress spurious warning
---
  b = NULL;  // Needed for the b->Put() below to shutup a compiler use-without-init warning
---
  #if _MSC_VER
  // Disable useless warnings about unreferenced formal parameters
  #pragma warning (disable : 4100)
  #endif
---
  #define LOG 0       // 0: disable logging, 1: enable it

  #ifdef _MSC_VER
  #pragma warning(disable: 4127)      // Caused by if (LOG)
  #endif // _MSC_VER
---

Note the uglification this makes for code by forcing useless statements to be added. If I hadn't put in the comments (and comments are often omitted) these things would be a mystery.
July 09, 2008
Nick Sabalausky wrote:
> It sounds like (previously unknown to me) there's a rift between the reality of warnings and the perceptions that many programmers (excluding us) have about warnings. As I understand it, you consider it more important to design around common perceptions of warnings, even if they're mistaken perceptions (such as warnings, by definition, not actually being errors). My disagreement is that I consider it better to design around the realities, and use a more education-based approach (I don't necessarily mean school) to address misperceptions. Is this a fair assessment of your stance, or am I still misunderstanding?

It's a fair assessment. I give more weight to designing a language around the way programmers are and the way they tend to work, rather than trying to force them adapt to the language.

As for the needs of programming managers, I think D is the only language that has attempted to address those needs. At least I've never ever heard of any other language even acknowledge the existence of such needs.
July 09, 2008
On Wed, 09 Jul 2008 12:49:34 +0400, Walter Bright <newshound1@digitalmars.com> wrote:

> Here are some horrid examples from my own code which, to please the client, had to compile with all warnings on for MSVC:
>
> ---
>    p = NULL;  // suppress spurious warning
> ---
>    b = NULL;  // Needed for the b->Put() below to shutup a compiler use-without-init warning
> ---
>    #if _MSC_VER
>    // Disable useless warnings about unreferenced formal parameters
>    #pragma warning (disable : 4100)
>    #endif
> ---
>    #define LOG 0       // 0: disable logging, 1: enable it
>
>    #ifdef _MSC_VER
>    #pragma warning(disable: 4127)      // Caused by if (LOG)
>    #endif // _MSC_VER
> ---
>
> Note the uglification this makes for code by forcing useless statements to be added. If I hadn't put in the comments (and comments are often omitted) these things would be a mystery.

We don't have problems with most of these in D, since there is no C-style macros and uninitialized variables.

Moreover, I would be happy to have an `unused` modifier in addition to in, out and inout (doh!) to denote that a variable is not going to be used. In this case compiler will show an error if the variable is used by chance. It could help programmer to catch potential bugs at early stage once he eventually start using it. Besides, it really fits well into D, IMO:

void bar( unused int foo ) // no warning is generated
{
}
July 09, 2008
Nick Sabalausky wrote:

> turned out to be variables I had intended to use but forgot to

I am trying to tackle such time wastings with "protocols" in drokue. If one would be able to formally attach ones intentions to variables then such bugs could possibly be prevented.

In your case the intention might have been to write and read the variable several times, of course starting with a write followed by some read. This intention can be expressed by a regular expression like:

   write+ read ( write | read )*

For evaluating this at runtime (!) one may attach a DFA to the variable---a DFA that interpretes the operations on the variable as input. Of course the DFA has to be initiated somewhere before the first operation on the variable. At program termination the DFA can than be checked, whether it is in a final state.

If at program termination the DFA is not in a final state then an "intention violation"-error can be reported. This way your time wouldn't have been wasted.

Please note, that such cannot be done by a lint tool.

-manfred
-- 
Maybe some knowledge of some types of disagreeing and their relation can turn out to be useful: http://blog.createdebate.com/2008/04/07/writing-strong-arguments/
July 09, 2008
Koroskin Denis:
> Moreover, I would be happy to have an `unused` modifier in addition to in,
> out and inout (doh!) to denote that a variable is not going to be used. In
> this case compiler will show an error if the variable is used by chance.
> It could help programmer to catch potential bugs at early stage once he
> eventually start using it. Besides, it really fits well into D, IMO:
> void bar( unused int foo ) // no warning is generated
> {
> }

Can you explain me in what practical situation(s) this can be useful?

Bye,
bearophile
July 09, 2008
On Wed, 09 Jul 2008 14:05:21 +0400, bearophile <bearophileHUGS@lycos.com> wrote:

> Koroskin Denis:
>> Moreover, I would be happy to have an `unused` modifier in addition to in,
>> out and inout (doh!) to denote that a variable is not going to be used. In
>> this case compiler will show an error if the variable is used by chance.
>> It could help programmer to catch potential bugs at early stage once he
>> eventually start using it. Besides, it really fits well into D, IMO:
>> void bar( unused int foo ) // no warning is generated
>> {
>> }
>
> Can you explain me in what practical situation(s) this can be useful?
>
> Bye,
> bearophile

It is the most useful if warning is generated when a variable is unused:

class Connection
{
   void connect(int timeout)
   {
       // do something
   }
}

class SomeOtherConnectionType : Connection
{
   void connect(unused int timeout)
   {
       // this type of connection is immediate, and therefore there is no need for timeout
       // but since we don't use timeout, just mark it unused

       // do the connection
   }
}

And then you realize that due to some specific changes this type of connection is no more immediate,
so now you are going to take it into account. And you see an unused modifier that says to you:

"Man, this variable was not used before, go check your code to see maybe there are some cases when you passed some dummy value to this function just to satisfy compilator, like this:

auto connection = new SomeOtherConnectionType();
connection.connect(0); // I don't care, since it is immediate anyway

and then refactor your code".
July 09, 2008
Koroskin Denis wrote:


>     void connect(unused int timeout)
[...]
> connection.connect(0); // I don't care, since it is immediate
> anyway
[...]
> and then refactor your code



In which way is this type of coding better than preparing for overloading `connect':

     void connect(){
       // ...
     }

     void connect( int timeout){
       // ...
       this.connect();
     }

and then calling

     > connection.connect(); // immediate connection



In addition: why is it good to be forced to refactor?

-manfred
-- 
Maybe some knowledge of some types of disagreeing and their relation can turn out to be useful: http://blog.createdebate.com/2008/04/07/writing-strong-arguments/
July 09, 2008
On Wed, 09 Jul 2008 15:26:54 +0400, Manfred_Nowak <svv1999@hotmail.com> wrote:

> Koroskin Denis wrote:
>
>
>>     void connect(unused int timeout)
> [...]
>> connection.connect(0); // I don't care, since it is immediate
>> anyway
> [...]
>> and then refactor your code
>
>
>
> In which way is this type of coding better than preparing for
> overloading `connect':
>
>      void connect(){
>        // ...
>      }
>
>      void connect( int timeout){
>        // ...
>        this.connect();
>      }
>
> and then calling
>
>      > connection.connect(); // immediate connection
>
>
>
> In addition: why is it good to be forced to refactor?
>
> -manfred

You asked an example, I provided one. There is another one:

class Node
{
    private Node parent;

    Node getRoot() {
        Node p = parent;
        while (parent !is null) {
            parent = parent.next;
        }

	return parent;
    }
}

Actually, getRoo() isn't supposed to modify this.parent, but it does by accident (say nothing about const, please!). In my code, I was going to modify local variable, but not a member. Local variable p was defined, it has value assigned but it's _not_ used. Compiler could warn me that I don't use it, and it would help to detect a problem.
July 09, 2008
Koroskin Denis wrote:

> You asked an example, I provided one. There is another one:
[...]

Bearophile asked for a _practical_ example. But your example seems to illustrate consequences rooted in a coding style and not rooted in the absence of an `unused' keyword and its semantics.


> I was going to modify local variable, but not a member.

This is a well known phenomenon. But again no need for an `unused' keyword shows up. To the contrary: within the function you want to use both variables, although one of them only for reading.

Pollution of the namspace within the function causes the problem. But would you really want to write import statements for variables from surrounding scopes?

> Compiler could warn me that I don't use it

This claim comes up once in a while, but seems to be unprovable in
general. It might be provable in your special case though. But without
the general proof one may have both:
- many false warnings
- many true bugs without warnings

Do you have a proof for the general case?

-manfred

-- 
Maybe some knowledge of some types of disagreeing and their relation can turn out to be useful: http://blog.createdebate.com/2008/04/07/writing-strong-arguments/