Hi Richard,

> -----Original Message-----
> From: Richard A. O'Keefe [mailto:[EMAIL PROTECTED]]
> Sent: Friday, April 26, 2002 2:50 AM
[...]
> "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.

Oh, no problem for me. I think I just didn't explain my problem exactly enough.

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

I see.

> 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'.

I didn't find the exact definition but that looks quite reasonable.

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

D'accord.

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

D'accord.

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

I agree that adding 'extern' will not fix the problem of inconsistent redeclarations 
of variables or functions - that can only do a
correction of the incorrect code.
However I think lclint/splint were right in recommending 'extern' here (if it were not 
a typedef but a variable or function),
because here they only warn because of a redeclaration. The warning because of an 
*inconsistent* redeclaration follows:

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

D'accord.

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

Certainly splint uses the C concept of scopes. I suppose it is just a bit incorrectly 
coded with respect to typedefs.

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

Sorry, my fault. Obviously I didn't think enough about it. I didn't realize the 
difference between the case you show in your own
example and that one you cite from my previous posting.

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

I agree, that should be the right behaviour.

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

Yes, that's true. And I personally hate it if two names in the same context (be it 
file names, variables or something else) are only
distinguishable by looking very carefully if there is some letter written in upper 
case or lower case.

So let's resume that splint behaves somewhat buggy with respect to typedefs.
Hopefully someone will find the time to fix it. :-)

Greetings
Martin


Reply via email to