Path: utzoo!attcan!uunet!lll-winken!lll-tis!ames!ucsd!ucsdhub!hp-sdd!ncr-sd!se-sd!rns From: rns@se-sd.sandiego.ncr.com (Rick Schubert) Newsgroups: comp.lang.c Subject: `char' parameters Summary: Help me find a reference Keywords: parameter, K&R, ANSI C Message-ID: <1616@se-sd.sandiego.ncr.com> Date: 31 Aug 88 16:34:36 GMT Reply-To: rns@se-sd.sandiego.NCR.COM (Rick Schubert) Organization: NCR Corp. Systems Engineering, San Diego Lines: 88 References: I believe I have found a bug in a C compiler I am using, but I cannot find anything in K&R I or the Draft ANSI Standard that <> addresses the issue. The compiler in question is pre-draft-ANSI, but I frequently look at the Draft in such situations where only K&R I features are involved. Anyway, the situation involves parameters of type `char'. Remember that this is pre-draft-ANSI, so that function prototypes do not exist. If I define a function `f' as follows: f(c) char c; { ... } the compiler in question gives a warning that type type of `c' is being changed to `int'. I could not find anything in K&R I or the Draft that addresses such parameters. The closest I could find is in K&R I section 2.7 (page 42): Since a function argument is an expression, type conversions also take place when arguments are passed to functions: in particular, `char' and `short' become `int', and `float' becomes `double'. This is why we have declared function arguments to be `int' and `double' even when the function is called with `char' and `float'. I was aware of what happens to the <>. The passage does not explain, however, what happens when one declares the parameter to be type `char' or `float'; I don't see this prohibited anywhere. To continue: when I first saw the warning from the compiler, I thought that the warning was invalid, since I thought that it was okay to declare such a parameter. I knew about the treatment of function <>, but I felt that, as long as the compiler generated code to reference the correct byte of the `int', that things would work out (this is what other compilers I have used have done). I even thought that it would be safe to ignore the warning, since, in most contexts, treating the parameter as an `int' or a `char' would not make any difference: in an expression, the `char' would be promoted to an `int'; on assignment, an `int' would be properly truncated to a `char'. The problem comes in taking the address of the parameter. Ignoring the problem that `&c' would produce an `int *' rather than a `char *', which byte does `&c' point to? The programmer who wrote `char c' would expect it to point to the byte containing the character that was passed to the function; i.e., in the following example: . . . f('A'); . . . f(c) char c; { g(&c); } g(p) char *p; { char c2; c2 = *p; } the programmer would expect `p' to point to a byte containing 'A', so that `c2' would be assigned 'A'. With the compiler in question, however, `p' points to the high-order byte of a word whose low-order byte is 'A', i.e. the word contains the value 0x00000041, and `p' points to 0x00 rather than 0x41, so that `c2' gets assigned 0x00 or '\0'. My questions are: 1. Is it illegal to declare a parameter to be of type `char'? 2. If not, is it valid to treat the parameter as type `int'? 3. If so, what does the unary `&' operator do to such a variable? 4. Where is this addressed in K&R I? 5. Where is this addressed in the Draft (assuming no prototypes)? Thanks for any useful information. -- Rick Schubert (rns@se-sd.sandiego.NCR.COM)