alanf@bruce.OZ (Alan Grant Finlay) (03/20/90)
I was surprised to discover that the Turbo-C package does not come with a lint program. Specifically I want to have the ability to automatically check for procedure argument type consistency. When in the past I have complained to C advocates that C compilers don't check for consistent use of parameters they have usually replied "that's what lint is for!". Is it really acceptable for a commercial compiler package to come supplied without an essential part or have I missed something in the package that does the same job? Also does anyone know if there are any public domain lints available that will work with Turbo-C source?
reino@cs.eur.nl (Reino de Boer) (03/20/90)
alanf@bruce.OZ (Alan Grant Finlay) writes: >I was surprised to discover that the Turbo-C package does not come with a lint >program. Specifically I want to have the ability to automatically check for >procedure argument type consistency. When in the past I have complained to Doesn't Turbo-C have a built-in checking mechanism ? Reino -- Reino R. A. de Boer Erasmus University Rotterdam ( Informatica ) e-mail: reino@cs.eur.nl
noren@dinl.uucp (Charles Noren) (03/21/90)
In article <1964@bruce.OZ> alanf@bruce.OZ (Alan Grant Finlay) writes: >I was surprised to discover that the Turbo-C package does not come with a lint >program.... Turbo C combines the lint checking with its compiler, thus you can optionally turn on all the lint diagnostics when you compile. The manual provides details on how to do this. -- Chuck Noren NET: ncar!dinl!noren US-MAIL: Martin Marietta I&CS, MS XL8058, P.O. Box 1260, Denver, CO 80201-1260 Phone: (303) 971-7930
dms@cs.arizona.edu (David Michael Shackelford) (03/21/90)
In article <1964@bruce.OZ>, alanf@bruce.OZ (Alan Grant Finlay) writes: > I was surprised to discover that the Turbo-C package does not come with a lint > program. Specifically I want to have the ability to automatically check for > procedure argument type consistency. When in the past I have complained to > C advocates that C compilers don't check for consistent use of parameters they > have usually replied "that's what lint is for!". Is it really acceptable for > a commercial compiler package to come supplied without an essential part or > have I missed something in the package that does the same job? > > Also does anyone know if there are any public domain lints available that will > work with Turbo-C source? I use Turbo-C's extended function prototype syntax and it checks for parameter type compatibility at the function calls. There might be an option in the compiler/warnings menu to cause it to give the message when types dont match. I compile with all error and warning messages enabled. As for the lint package, I don't know of any. Maybe someone else has an idea.. There might be a portability problem with using Turbo's extended prototypes, so if you're planning on porting, beware...
alanf@bruce.OZ (Alan Grant Finlay) (03/21/90)
In article <1990Mar20.130947.16583@cs.eur.nl>, reino@cs.eur.nl (Reino de Boer) writes: > > Doesn't Turbo-C have a built-in checking mechanism ? > In article <1555@dinl.mmc.UUCP>, noren@dinl.uucp (Charles Noren) writes: > Turbo C combines the lint checking with its compiler, thus you can optionally > turn on all the lint diagnostics when you compile. The manual provides > details on how to do this. > -- Both of these were in reponse to my original query which may not have been specific enough. Consider the following correct program: check(x,y) long x; char *y; { printf("%10.10s ",y); } main() { check(10l,"testing"); } If you now remove the l after the 10 in the procedure call the compiler issues no relevant warnings and the program misbehaves. Can Turbo-C generate a warning for this kind of error?
bobmon@iuvax.cs.indiana.edu (RAMontante) (03/21/90)
alanf@bruce.OZ (Alan Grant Finlay) <1966@bruce.OZ> : -main() -{ -check(10l,"testing"); -} - -If you now remove the l after the 10 in the procedure call the compiler -issues no relevant warnings and the program misbehaves. Can Turbo-C -generate a warning for this kind of error? The "Portability Warnings" sub-sub-sub-menu includes `long constant' warnings as well as others. Go through the Options menu and turn on all the warnings and errors that you care about. They're all available in the command-line version as well. The factory default turns most of these off, so you may not have known they were there.
martinr@cpqhou.UUCP (Martin Richek) (03/21/90)
In article <1990Mar20.130947.16583@cs.eur.nl>, reino@cs.eur.nl (Reino de Boer) writes: > alanf@bruce.OZ (Alan Grant Finlay) writes: > > >I was surprised to discover that the Turbo-C package does not come with a lint > >program. Specifically I want to have the ability to automatically check for > >procedure argument type consistency. When in the past I have complained to > > Doesn't Turbo-C have a built-in checking mechanism ? > Yes, it does. Use the highest warning level.
reino@cs.eur.nl (Reino de Boer) (03/21/90)
alanf@bruce.OZ (Alan Grant Finlay) writes: >Both of these were in reponse to my original query which may not have been >specific enough. Consider the following correct program: >check(x,y) >long x; >char *y; >{ >printf("%10.10s ",y); >} >main() >{ >check(10l,"testing"); >} >If you now remove the l after the 10 in the procedure call the compiler >issues no relevant warnings and the program misbehaves. Can Turbo-C >generate a warning for this kind of error? lint (Sun OS 4.0.3): -------------------- test.c(2): warning: argument x unused in function check check, arg. 1 used inconsistently test.c(4) :: test.c(9) printf returns value which is always ignored Turbo-C: -------- (Not exactly reproduced) Parameter x never used in function check Function should return a value in function check Function should return a value in function main We can conclude that Turbo-C's checking mechanism does not detect that parameter 'x' is used inconsistently, and that lint does not complain about the lack of return statements. Hope this answers your question, Reino P.S. Turbo-C also complains about the lack of prototypes for 'check' and 'printf'. -- Reino R. A. de Boer Erasmus University Rotterdam ( Informatica ) e-mail: reino@cs.eur.nl
teittinen@cc.helsinki.fi (03/21/90)
In article <1966@bruce.OZ>, alanf@bruce.OZ (Alan Grant Finlay) writes: > check(x,y) > long x; > char *y; > { > printf("%10.10s ",y); > } > main() > { > check(10l,"testing"); > } > > If you now remove the l after the 10 in the procedure call the compiler > issues no relevant warnings and the program misbehaves. Can Turbo-C > generate a warning for this kind of error? Why are you using old style function definitions, if you're interested of getting rid of bugs? If you write the check function again using ANSI-style function definition (void check(long x, char *y)) the compiler does automatic type conversion and no errors occur. Why make easy things difficult? -- E-Mail: teittinen@finuh.bitnet ! "Studying is the only way teittinen@cc.helsinki.fi ! to do nothing without Marko Teittinen, student of computer science ! anyone blaming you" -me
noren@dinl.uucp (Charles Noren) (03/22/90)
In article <1966@bruce.OZ> alanf@bruce.OZ (Alan Grant Finlay) writes: >In article <1990Mar20.130947.16583@cs.eur.nl>, reino@cs.eur.nl (Reino de Boer) writes: >In article <1555@dinl.mmc.UUCP>, noren@dinl.uucp (Charles Noren) writes: >Both of these were in reponse to my original query which may not have been >specific enough. Consider the following correct program: > >check(x,y) >long x; >char *y; >{ >printf("%10.10s ",y); >} >main() >{ >check(10l,"testing"); >} > >If you now remove the l after the 10 in the procedure call the compiler >issues no relevant warnings and the program misbehaves. Can Turbo-C >generate a warning for this kind of error? My Turbo C stuff is at home... but I suggest you use the ANSI C features of the compiler, so your code would become: void check(long x, char *y) /* I always want to explicitly say what the function returns, in this case nothing (the previous definition returned an int). */ { printf("%10.10s ", y); } main() { check(10l, "testing"); } ...now Turbo C, under its default settings, will check the argument list in the function check(). If the "l" is taken out, Turbo C will let you know. Turbo C should also tell you that you did not use argument x in function check(). These are the "lintish" features of the compiler. You can turn off the unused argument check by using a #pragma statement as documented in the Turbo C manuals (this corresponds to a same lint capability). As another poster has mentioned, the default checks on your code by Turbo C, while more than "standard" C compilers, is rather limited. Check the documentation for turning on more of the checks. -- Chuck Noren NET: ncar!dinl!noren US-MAIL: Martin Marietta I&CS, MS XL8058, P.O. Box 1260, Denver, CO 80201-1260 Phone: (303) 971-7930
alawrenc@sobeco.com (a.lawrence) (03/24/90)
From article <1964@bruce.OZ>, by alanf@bruce.OZ (Alan Grant Finlay): > I was surprised to discover that the Turbo-C package does not come with a lint > program. Specifically I want to have the ability to automatically check for > procedure argument type consistency. When in the past I have complained to > C advocates that C compilers don't check for consistent use of parameters they > have usually replied "that's what lint is for!". Is it really acceptable for > a commercial compiler package to come supplied without an essential part or > have I missed something in the package that does the same job? I think you had better take a second look at your compiler. If you turn on all the warning levels, it will do a much better job verifying your code than most lint programs. Turbo C has often found serious problems in programs which compiled and linted corrected on UNIX. As far as function definitions go, if you use ANSI style function prototypes Turbo C which check all of you function calls very closely, and even report a warning when the code you right is acceptable C but probably not what you wanted (suspicious pointer casts, etc). If you want the code you are developing to be portable to non-ANSI compilers use the following macro: #ifdef ansi_style #define P(x) x #else #define P(x) () #endif and code your function prototype as: char *function P((int num, har *string)); --- On a clear disk you can seek forever. ------------------------------------------------------------------------- Andrew Lawrence | alawrenc@sobmips.sobeco.UUCP Informaticien Conseil | {attcan,mcgill-vision}!sobeco!sobmips!alawrenc 3462 Jeanne-Mance, #1 | Montreal, Que CANADA | Voice (514) 281-5196
dfoster@jarthur.Claremont.EDU (Derek R. Foster) (03/25/90)
In article <1990Mar21.110835.29391@cs.eur.nl> reino@cs.eur.nl (Reino de Boer) writes: >alanf@bruce.OZ (Alan Grant Finlay) writes: >> Consider the following correct program: >>check(x,y) >>long x; >>char *y; >>{ >>printf("%10.10s ",y); >>} >>main() >>{ >>check(10l,"testing"); >>} > >>If you now remove the l after the 10 in the procedure call the compiler >>issues no relevant warnings and the program misbehaves. Can Turbo-C >>generate a warning for this kind of error? >[The output from Turbo C with all warnings turned on is compared to > that of lint. Turbo C does not comment on the call of check involving > an int.] >We can conclude that Turbo-C's checking mechanism does not detect that >parameter 'x' is used inconsistently, >Reino R. A. de Boer >Erasmus University Rotterdam ( Informatica ) >e-mail: reino@cs.eur.nl The reason that Turbo-C doesn't report an error for this is that for Turbo-C, it ISN'T an error. For two reasons: 1) when you prototyped check(x,y); what were are essentially telling Turbo C is "I'm going to declare a function, and it takes two arguments, but it's none of your business what type those arguments are. Let me deal with it." So Turbo C respects that request, and does no type checking other than to verify that the correct number of arguments are passed. 2) If you had prototyped void check(long x, char * y); or declared your function as void check(long x, char * y) { ... } you would have told Turbo C "I'm declaring a function that has no return value and takes two arguments: a long value and a character pointer. If I try to pass ^^^^^^^^^^^^^^^^ anything else to it, try to convert what I pass to a long and a ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ character pointer, respectively. If you can't, report an error." You CAN pass an int value to a function which takes a long parameter. It will simply be sign-extended if necessary, so that the value that the function recieves as a long represents the same number that was passed as an int. Passing a long value to an function which takes an int parameter will provoke the warning "Conversion may lose significant digits", and will essentially chop off the most significant bytes, still attempting to preserve the sign. These automagic conversions of values can take place between many kinds of VALUES (not pointers), including char <-> int signed whatever <-> unsigned whatever int <-> float (I'm not sure about float->int. I think C just truncates after the decimal, but I'm not certain. Rounding is also possible, or requiring an explicit cast. This is a tricky one even under the best of circumstances.) (I'm also not sure about int<->enum or int<->typedef int xxx) Note that while an attempt to send an int to a function which takes a long parameter is legal, an attempt to send an (int *) to a function that takes a (long *) is illegal and will provoke a "non-portable pointer assignment" warning or somesuch, since the compiler can't really compile conversion code into every statement that might use indirection on the pointer. So you see, the reason that Turbo C doesn't complain about your leaving off the "l" on the constant is (1) because you haven't prototyped check() properly, and (2) even if you did, Turbo C would simply convert the int to a long and then end up passing the same value to check(). It's not that Turbo C has inadequate error-CHECKING abilities. Instead, it has greater potential error HANDLING. Side note: This is also (I think) a reason why the value NULL should be able to be passed to functions which take other than (void *) parameters, without explicit casting. If the function is prototyped properly, the compiler should recognize that since NULL has type (void *) and the function accepts a (char *), for instance, that a conversion may be necessary if the value "NULL" in a (char *) is different from that in a (void *). Or why you don't need to say memcpy((void *) &x, (void *) &y, len), as someone has suggested recently. The (void *) cast is implicit in the prototype of memcpy as "void * memcpy(void * x, void * y, size_t z)" (or something similar -- this is off the top of my head.), and the compiler shouldn't even issue a warning for implied casts to and from a (void *). Passing a (char *) to an (int *) will probably give you a warning message, but it can STILL technically be handled, even if the representations of the pointers are different. (I would not suggest you do this, however! It is rather nonportable! Anything to/from a void * should be OK, however) BTW, I would like to know how much of this if this is standard behavior for ANSI C, and how much is Turbo C extensions. What does the standard say? I hope this clears up some confusion! Derek Riippa Foster
darcy@druid.uucp (D'Arcy J.M. Cain) (03/26/90)
In article <1964@bruce.OZ> alanf@bruce.OZ (Alan Grant Finlay) writes: >I was surprised to discover that the Turbo-C package does not come with a lint >program. Specifically I want to have the ability to automatically check for >procedure argument type consistency. When in the past I have complained to >C advocates that C compilers don't check for consistent use of parameters they >have usually replied "that's what lint is for!". Is it really acceptable for >a commercial compiler package to come supplied without an essential part or >have I missed something in the package that does the same job? > >Also does anyone know if there are any public domain lints available that will >work with Turbo-C source? In Turbo-C (2.0 at least) lint is effectively built in. As long as the functions are prototyped (and this is true for all of their library functions if you include the proper header files) then you can be warned of all these sorts of things. You must turn on the warnings with a switch but these can be turned on as a default in your configuration file. I think that this type of checking is true for all compilers that try to be ANSI compliant. That is the point of prototyping - to be able to check each call for errors. -- D'Arcy J.M. Cain (darcy@druid) | Thank goodness we don't get all D'Arcy Cain Consulting | the government we pay for. West Hill, Ontario, Canada | (416) 281-6094 |
darcy@druid.uucp (D'Arcy J.M. Cain) (03/26/90)
In article <1966@bruce.OZ> alanf@bruce.OZ (Alan Grant Finlay) writes: > [...] >check(x,y) >long x; >char *y; >{ >printf("%10.10s ",y); >} >main() >{ >check(10l,"testing"); >} > >If you now remove the l after the 10 in the procedure call the compiler >issues no relevant warnings and the program misbehaves. Can Turbo-C >generate a warning for this kind of error? Yes if you code it properly (the ANSI way) as follows: void check(long x,char *y) { printf("%10.10s ",y); } main() { check(10l,"testing"); } The 'l' is now no longer necessary. You won't get a warning message because it will behave correctly. The compiler knows when calling "check" that the first argument is a long and does the promotion. As K&R2 says (pp 202): "If the function declaration in scope for a call is new-style, then the arguments are converted, as if by asignment, to the types of the corresponding parameters of the function's prototype." Of course if the type can't be converted this fails but a suitable error message will be generated. This will catch the following error: check("testing", 10); -- D'Arcy J.M. Cain (darcy@druid) | Thank goodness we don't get all D'Arcy Cain Consulting | the government we pay for. West Hill, Ontario, Canada | (416) 281-6094 |
jimp@cognos.UUCP (Jim Patterson) (04/11/90)
In article <90033012502875@masnet.uucp> david.megginson@canremote.uucp (DAVID MEGGINSON) writes: >alawrenc@sobeco.com writes: >>If you want the code you are developing to be portable to non-ANSI >>compilers use the following macro: >> >> #ifdef ANSI_style >> >Whoa, let's not get non-standard already. Why use > > #ifdef ANSI_style > >instead of the ANSI standard > > #ifdef __STDC__ > >which all strict ANSI compilers should define automatically? Using your own symbol instead of __STDC__ isn't non-standard, and there are good reasons for avoiding scattering #ifdef __STDC__ all through a large product. Sure, all strict ANSI compilers will define __STDC__. However, a really strict ANSI compiler won't define __STDC__ if it's compiling in a mode that isn't strictly ANSI (e.g. if stdio.h defines some externals that aren't in the ANSI standard; that's namespace polution). What's more, it won't let YOU define __STDC__ (it's reserved). This doesn't mean that it won't support prototypes. (Yes, there are such compilers). There is also the converse problem. Some not-fully-ANSI compilers define __STDC__, but to be some other value e.g. 0. It's conceivable that a compiler vendor might define __STDC__ but might not support prototypes, or they might have a bug which prevents their use. After all, ANSI can't proscribe the actions of compiler venders who don't support the ANSI standard (though there's a pretty wide concensus that such vendors are being quite anti-social). So, using your own manifest name instead of __STDC__ is a good idea. If your project has a common #include file as many do, then you can #define your manifest there based on __STDC__ or whatever else is appropriate, e.g. #ifdef __STDC__ #if __STDC__ == 1 #define ANSI_style #endif #endif -- Jim Patterson Cognos Incorporated UUCP:decvax!utzoo!dciem!nrcaer!cognos!jimp P.O. BOX 9707 PHONE:(613)738-1440 3755 Riverside Drive Ottawa, Ont K1G 3Z4
madhyani@ucf-cs.ucf.edu (04/20/90)
/* Written 1:32 am Mar 20, 1990 by alanf@bruce.UUCP in ucf-cs.ucf.edu:comp.lang.c */ >/* ---------- "turbo-C and lint ?" ---------- */ >I was surprised to discover that the Turbo-C package does not come with a lint >program. Specifically I want to have the ability to automatically check for >procedure argument type consistency. When in the past I have complained to >C advocates that C compilers don't check for consistent use of parameters they >have usually replied "that's what lint is for!". Is it really acceptable for >a commercial compiler package to come supplied without an essential part or >have I missed something in the package that does the same job? > >Also does anyone know if there are any public domain lints available that will >work with Turbo-C source? >/* End of text from ucf-cs.ucf.edu:comp.lang.c */ Are you using Turbo-C 2.0. If so, then you haven't dig into the menus. Turbo C provides all the lint features you can find in 'UNIX lint'. Read the manual, Hack the Main menu. Good Luck! -- Bharat madhyani madhyani@ucf-cs.ucf.edu