"Martin Roehrig" <[EMAIL PROTECTED]> wrote:
        Right, but that was not the problem.  As you see in the code the
        header is just included once by each of the .c files.

I am afraid I was in a hurry that day and did not read the code carefully.
I apologise to all readers of this mailing list.

However, my point that the wording of the message is definitely wrong
(because 'extern typedef ...' is illegal) stands.
        
        The problem is that splint mingles the two includes although
        they never come together in the same *compilation* unit.

Let me give an example where the same name is used for two different
types, but no error results:

f% cat >a.h
typedef int mytype;

f% cat >b.h
typedef double mytype;

f% cat >a.c
#include "a.h"
mytype x;

f% cat >b.c
#include "b.h"
mytype y;

f% cat >ab.c
extern int x;
extern double y;
int main(void) {x = 0; y = 0.0; return x;}

f% lint a.c b.c ab.c
a.c:
b.c:
ab.c:

Lint (in this case the one that comes with SPARCompiler C for Solaris 2.8)
does not report any errors.  It is correct in so doing, because there ARE
no errors.  The scope of a typedef is the same as the scope of an otherwise
similar 'static'.

Contrast this with lclint:
f% lclint a.c b.c ab.c
LCLint 2.5m --- 20 May 2000

b.h:1:16: Datatype mytype defined more than once
  A function or variable is redefined. One of the declarations should use
  extern. (-redef will suppress message)
   a.h:1:13: Previous definition of mytype

BUG 1:  The two scopes do not overlap in any way at all.
This is perfectly legal code.

BUG 2:  The message mentions 'A function or variable', and 'mytype'
is neither.

BUG 3:  If a function or variable is redefined with a different type,
as LClint thinks happens here, adding 'extern' will NOT fix the problem.


b.h:1:16: Datatype mytype redeclared with inconsistent type: double
  A function, variable or constant is redefined with a different type.
  (-incondefs will suppress message)
   a.h:1:13: Previous definition of mytype: int

Bug 1 consequence.
Bug 2 puts in another appearance.

ab.c:2:15: Variable y redeclared with inconsistent type: double
   b.c:2:8: Previous definition of y: mytype

BUG 4:  y is consistently declared to be 'double'.
Possibly a consequence of Bug 1.

ab.c: (in function main)
ab.c:3:24: Assignment of double to mytype: y = 0.0
  Types are incompatible. (-type will suppress message)

Another consequence of bug 1.

Finished LCLint checking --- 4 code errors found

Splint 3.0.1.6 --- 11 Feb 2002

produces exactly the same incorrect messages.


Somehow, a typedef name at global scope should be "tagged" with the
exact source file that it comes from, so that splint can realise
that "a.h`mytype" and "b.h`mytype" are distinct, and only cause
problems if they occur in the same translation unit.

        However it cannot but do so as it would miss some errors
        otherwise:
        
        --------------- header1.h -------------
        typedef int mytype;
        ---------------------------------------
        
        --------------- header2.h -------------
        typedef double mytype;
        ---------------------------------------
        
        --------------- code1.c ---------------
        #include "header1.h"
        extern mytype myvar;
        ---------------------------------------
        
        --------------- code2.c ---------------
        #include "header2.h"
        mytype myvar;
        ---------------------------------------
        
Sorry, this is an unsound argument.

f% cat >a.h
typedef int mytype;

f% cat >a.c
#include "a.h"
extern mytype x;
int main(void) {return x = 0;}

f% cat >b.h
typedef double mytype;

f% cat >b.c
#include "b.h"
mytype x = 2.5;

f% lint a.c b.c
a.c:
b.c:

value type declared inconsistently
    x                   b.c(2) double  :: a.c(2) int 

Lint does NOT get a.h`mytype muddled up with a.b`mytype, but DOES
notice that x is declared with two different types.

Anyone who has used Unix Lint is familiar with the fact that it operates
in two "passes".  In pass 1 it processes each file *separately*.  If there
are any gross errors it stops and does not run pass 2.  In pass 2, it
merges all the abstracts produced in pass 1 and checks them for consistency.

I am _not_ saying that SPlint can or should operate the same way.
I've already suggested another means to the same end.

typedef names are not functions or variables and should not be subject
to the same rules.
          Perhaps splint should warn
        > if that happens
        >     Warning: file may be included under two different names:
        >       <lino1> myheader.h
        >       <lino2> MYHEADER.H
        
        Nice idea.  David, what about that as one aspect of the flag you
        proposed for the next release?  Of course it makes only sense on
        a file system that really doesn't make a difference between
        lower case and upper case letters.
        
Oh no.  If you are thinking of porting a program _from_ UNIX _to_ Windows
or MacOS (pre MacOS X), then it is useful to be warned that two things you
thought were different may be identified.


Reply via email to