Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site calgary.UUCP Path: utzoo!watmath!clyde!burl!mgnetp!ihnp4!alberta!calgary!radford From: radford@calgary.UUCP (Radford Neal) Newsgroups: net.lang.c Subject: C pre-processor and ANSI standard Message-ID: <572@calgary.UUCP> Date: Fri, 7-Sep-84 17:02:29 EDT Article-I.D.: calgary.572 Posted: Fri Sep 7 17:02:29 1984 Date-Received: Thu, 13-Sep-84 19:02:56 EDT Organization: U of Calgary, Calgary, Alberta Lines: 79 A number of articles have been posted recently regarding the C pre-processor and the new C standard. None of the none of the authors seem to take the correct -:) view that the C pre-processor is a complete botch and should be discarded as soon as possible. How many macro definitions like the following have you seen? #define min(a,b) a>b ? b : a The correct definition is #define min(a,b) ((a)>(b) ? (b) : (a)) but few programmers are that careful. If you don't see the difference, try the expressions x+min(y,z) and min(1,q?x:z). If you think you'd never be that careless, go on to trying to write a macro to write N spaces to standard output. This is IMPOSSIBLE if you want the macro call to look like a procedure call. The best you can do is the following: #define spaces(n) { int i; for (i = (n); i>0; i--) putchar(' '); } This naturally doesn't work in a call such as spaces(i*2) (no concept of scope!). Furthermore, the following code segment doesn't work: if (blat) spaces(10); else spaces(20); (You have to remove the first semi-colon). The present pre-processor is also a fertile ground for programmers who like to write obscure and misleading code. A relatively mild form of this is the following sort of macro: #define clear(v) ((v) = 0) A call such as clear(i) looks just like a procedure call but alters its argument, which would be impossible if it really was one. Finally, the pre-processor doesn't fit with the rest of C syntax from an aesthetic point of view. The commands can't be indented and they treat end-of-line as significant, both contrary to the rest of the language. I suggest that the new standard include a minimal form of the present pre-processor for compatibility plus the following two new constructs which would be preferred for most of the legitimate uses. 1) Allow a storage-class of 'const'. Examples would be const int a = 1234; const struct point origin = { 0.0, 0.0 }; The initialization would be optional for global const's, but would be expected in some module. Integer constants initialized in the current module could be used in array bounds, etc. You could take the address of a constant. The compiler could figure out whether it really needed to allocate space for it (in a write-protected area of course). 2) Allow a "storage-class" of 'inline' for procedures. For example: inline int min(a,b) int a, b; { return a>b ? b : a; } Semantics identical to ordinary procedures except you can't get pointers to them. Any decent compiler would generate in-line code for these, which shouldn't be too difficult since C already has declarations in inner blocks. The only legitimate use of a real macro-like facility I can see is for conditional compilation, and even that might be better done in most cases by a compiler that's smart enough to recognize if statements with constant conditions. Radford Neal, University of Calgary, Calgary, Alberta, CANADA