dapermezel@watmath.UUCP (Damon Permezel) (10/01/83)
The addition of the ability to type the expected args of an external function is definitely needed in C. All you VAX-C programmers have lead a sheltered life and can't be expected to realise the need. Consider the much abused f(0); where 'f' is f(p) char *p; { ... } This works fine on the VAX, but will not work on a HW level-6, which has different sizes for each of 'int', 'int *' and 'char *'. It will also fail on the 68000, where sizeof(int) == 2 and sizeof(int *) == sizeof(char *) == 4. When we ported our compiler source from the HW DPS/8 (sizeof(most_stuff) == 4) to the level-6, we had one hell of a time (we had no lint then). If my language extension that allows extern f(char *); had been working then, most of the problems would have gone away with the inclusion of a "ext_def.h" file that defined the arg types, allowing the compiler to add the cast where necessary. I was very reluctant to add any language extensions to my parser, but this one i definitely consider worthwhile. =damon
notes@ucbcad.UUCP (10/02/83)
#R:watmath:-587000:ucbesvax:4800025:000:2310 ucbesvax!turner Oct 1 18:00:00 1983 I, like, totally grok what you mean. The problem of C not knowing (or much caring) about types of arguments of external functions is not completely alleviated by lint, since, to be fully useful, we would also want to have pointers to functions, with argument-types checked. (lint can't do this, in general, so it doesn't do it at all.) I have an interesting little hack, which works for my situation. I am charged with defining and maintaining (not mention implementing), a special-purpose database. To provide a security blanket, I define all entry-points in a global #include file as macros, where the *real* names of access routines are all icked-out with underscores. This takes care of *numbers* of arguments (since cpp complains of argument mismatches). But what about the *types* of arguments? My people here don't use lint (and their code shows it!), so giving them a lint library is no help. After a bit of C-puzzling, I came up with the following ultra-cutesy- but-probably-portable macro: #define _declare_(Expr,Type) ( sizeof((Expr) == (Type) 0), (Expr) ) /* Example: */ extern SomeStruct *_Icky_Real_Name_( ); #define FakeName(arg1,arg2) \ _Icky_Real_Name_( _declare_(arg1,char *), \ _declare_(arg2,SomeStruct) ) Now, calls through FakeName must have exactly two arguments, one (char *), the next of type SomeStruct, if they are to compile without errors. Exegesis of "_declare_": "( sizeof(...), (Expr) )" = (Expr), loosely speaking; sizeof(...) is a constant, and the code generator throws it out, since a constant can't have side-effects. The comma operator was a good idea. Also, sizeof(...) suppresses any code generation for (...). Thus we circumvent a problem with macros: that multiple mentions of a formal parameter involve multiple evaluations of the actual parameter--bad craziness, but we get around it here. Finally, "(Expr) == (Type) 0" will generate an error message, if the type of Expr is incomparable with something of type Type. But, given a choice, I would rather exercise my remaining inventive powers in ways other than hacking around holes in C. Especially considering that my inventive powers are out to lunch a lot, these days. No Strong-Typing vs. Weak-Typing Jihads, Please, Michael Turner (ucbvax!ucbesvax.turner)
thomas@utah-gr.UUCP (Spencer W. Thomas) (10/03/83)
Note: lint flags f(0) as a type mismatch, if f() has a pointer argument. This is true even if you are not asking for portability checks. (This is under 4.1Bsd.) =S