Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!linus!decvax!ittvax!dcdwest!sdcsvax!sdcrdcf!hplabs!sri-unix!craig@BBN-LABS-B.ARPA From: craig@BBN-LABS-B.ARPA Newsgroups: net.lang.c Subject: expressions and #if Message-ID: <1836@sri-arpa.UUCP> Date: Tue, 10-Jul-84 07:59:00 EDT Article-I.D.: sri-arpa.1836 Posted: Tue Jul 10 07:59:00 1984 Date-Received: Sun, 15-Jul-84 10:01:57 EDT Lines: 84 From: Craig Partridge [I don't believe I have seen this issue discussed before, though I was off the net for a while]. I have been working a little bit on extending a program that reads C programs and replaces all #ifdef'ed code with the code for which the condition applies. I.e. given the code ------------------- #ifdef FOO a = b; #else b = a; #endif ------------------- and FOO not defined, the program replaces all this stuff with simply ------------------- b = a; ------------------- My extension is to add support for the #if statement, and I have run into several definitional problems. The problems come from several different directions -- I will try to break them up logically. The definition of #if is that it evaluates a constant-expression (K&R 12.3 and 15). But constant-expression is not very well defined. First, it is only defined for case, array bounds and initializers. The definitions differ between the first two and initializers. Since initializers seem to be viewed as a very exceptional case, I have assumed that #if is akin to case or array bounds. In these cases a constant-expression is defined as involving "only integer constants, character constants, and sizeof expressions, possibly connect by the binary operators + - * / % & | ^ << >> == != < > <= >= or by the unary operators - ~ or by the ternary operator ?: Parentheses can be used for grouping, but not for function calls" O.K. now for the problems: (1) the unary operator ! is not included in the list of legitimate operators. This makes #if much less useful. Any views on whether this is intentional or just a typo? Same question for && and ||. (2) The Berkeley code seems to include a new macro operator defined(x) which returns 1 if x is defined, 0 otherwise. Is this now a generally accepted feature or just a Berkeley extension? (3) the fact that two types of constants raises some interesting troubles. Is one required to support type casts in the constant-expression? (4) Related to (3), must sizeof(expression) be supported? If so can "expression" be any expression or just a constant-expression? Can "expression" contain type casts? (5) /lib/cpp on 4.2 supports a few features that are not mentioned in the standards. For example, the comma operator is supported in the constant-expression. Are there other extensions people know of -- are they generally accepted? (6) A nice definitional problem to finish off the list. #if is clearly a preprocessor statement. But there is no definition in the manual of how much the preprocessor is supposed to know about. The manual says simply that the preprocessor is "capable of macro substitution, conditional compilation and inclusion of include files." No mention is made of expression handling, although #if clearly requires it. Just how bright is the preprocessor required to be? Interested to hear people's views, Craig Partridge craig@bbn-unix (ARPA) bbncca!craig (USENET)