joep@tnosoes.UUCP (Joep Mathijssen) (02/14/90)
Look at this C-code:
#define MAX -32768
main()
{
printf("1: %d\n", MAX);
printf("2: %d\n", (int)MAX);
}
Result:
1: -1
2: -32768
===============================================================================
Joep Mathijssen
TNO Institute for Perception
P.O. Box 23 Phone : +31 34 63 562 11
3769 ZG Soesterberg E-mail: tnosoes!joep@mcvax.cwi.nl
The Netherlands or: uunet!mcvax!tnosoes!joep
===============================================================================
ericco@stew.ssl.berkeley.edu (Eric C. Olson) (02/15/90)
>Look at this C-code: > #define MAX -32768 > main() > { > printf("1: %d\n", MAX); > printf("2: %d\n", (int)MAX); > } This is not a bug, its a feature. MAX is not a number, its an expression. Thus, the evaluation of MAX is a long int. The first printf only prints the high word of the long int MAX. The second printf properly casts the long int to an int and prints the correct result. Try: printf("3: %ld\n", MAX); Eric ericco@sag4.ssl.berkeley.edu Eric ericco@ssl.berkeley.edu
hcj@lzsc.ATT.COM (HC Johnson) (02/15/90)
In article <1990Feb14.173746.28244@agate.berkeley.edu>, ericco@stew.ssl.berkeley.edu (Eric C. Olson) writes: > >Look at this C-code: > > #define MAX -32768 > > main() > > { > > printf("1: %d\n", MAX); > > printf("2: %d\n", (int)MAX); > > } > > This is not a bug, its a feature. MAX is not a number, its an expression. > Thus, the evaluation of MAX is a long int. The first printf only prints K&R specify that constants are int's. Not a long int. > the high word of the long int MAX. The second printf properly casts the > long int to an int and prints the correct result. Try: > > printf("3: %ld\n", MAX); > This is probably an example of the compiler maker trying to be nice. And breaking the users code in the process. Howard C. Johnson ATT Bell Labs =====NEW address==== att!lzsc!hcj hcj@lzsc.att.com stupid mailer:
saj@chinet.chi.il.us (Stephen Jacobs) (02/16/90)
My two cents on the behavior of the 'constant' -32768 in C. If something is #define ed as -32768, remember that that means a _textual_ substitution will be made wherever that thing appears (in contrast to a numeric substitution). So the normal rules for integer constants apply (rather than some special rule that might apply to preprocessor actions: the preprocessor action is simple). Integer constants don't have leading signs. -32768 gives the result of applying unary minus to the integer constant 32768. And on a 16 bit model compiler, there isn't an integer 32768. So the value of -32768 is free to vary depending on context. One hopes a warning message is generated (it is in Mark Williams C). Frankly, -32768 is such a convenient value for flags on a 2-s complement machine, that I'd like integer constants to have an optional leading sign, but it isn't defined that way. Steve J.
roland@cochise.pcs.com (Roland Rambau) (02/19/90)
hcj@lzsc.ATT.COM (HC Johnson) writes:
->> >Look at this C-code:
->> > #define MAX -32768
->> > main()
->> > {
->> > printf("1: %d\n", MAX);
->> > printf("2: %d\n", (int)MAX);
->> > }
->>
->> This is not a bug, its a feature. MAX is not a number, its an expression.
->> Thus, the evaluation of MAX is a long int. The first printf only prints
->K&R specify that constants are int's. Not a long int.
If I remember well, TC will give you a WARNING when it finds a constant
which is too long to fit in an int and therefor will be interpreted as long.
Corollary: Do not turn off any warning.
--
I know that You believe You understand what You think I said, but
I'm not sure You realize that what You heard is not what I meant.
Roland Rambau
rra@cochise.pcs.com, {unido|pyramid}!pcsbst!rra, 2:507/414.2.fidonet
--
I know that You believe You understand what You think I said, but
I'm not sure You realize that what You heard is not what I meant.
ericco@stew.ssl.berkeley.edu (Eric C. Olson) (02/22/90)
roland@cochise.pcs.com (Roland Rambau) writes: >hcj@lzsc.ATT.COM (HC Johnson) writes: >->> > #define MAX -32768 >->> > main() >->> > { >->> > printf("1: %d\n", MAX); >->> > printf("2: %d\n", (int)MAX); >->> > } >->> >->> This is not a bug, its a feature. MAX is not a number, its an expression. >->> Thus, the evaluation of MAX is a long int. The first printf only prints >->K&R specify that constants are int's. Not a long int. Like I said "MAX is not a number, its an expression." There is an integer in the expression (the number 32768). But there is also an operator (the unary minus). This makes MAX an expression, not a number. Thus the real question is what does K&R say integer expression are evaluated to? I don't have K&R handy, but I believe it says long ints. Eric ericco@ssl.berkeley.edu Eric ericco@ssl.berkeley.edu
mce@sdcc10.ucsd.edu (Mark Edwards) (03/02/90)
In article <1990Feb21.204744.560@agate.berkeley.edu> ericco@stew.ssl.berkeley.edu (Eric C. Olson) writes: #roland@cochise.pcs.com (Roland Rambau) writes: #>hcj@lzsc.ATT.COM (HC Johnson) writes: #>->> > #define MAX -32768 #>->> > main() #>->> > { #>->> > printf("1: %d\n", MAX); #>->> > printf("2: %d\n", (int)MAX); #>->> > } #>->> #>->> This is not a bug, its a feature. MAX is not a number, its an expression. #>->> Thus, the evaluation of MAX is a long int. The first printf only prints #>->K&R specify that constants are int's. Not a long int. # #Like I said "MAX is not a number, its an expression." There is an integer #in the expression (the number 32768). But there is also an operator (the #unary minus). This makes MAX an expression, not a number. Thus the real #question is what does K&R say integer expression are evaluated to? I #don't have K&R handy, but I believe it says long ints. # K&R, second edition, section A8.2 type specifiers offers these useful quotes: 1. If the type specifier is mission from a declaration, it is taken to be an int 2. The signed specifier is useful for forcing char objects to carry a sign; it is permissible but redundant with other integral types. 3. At most one of the words long or short may be specified together with int; the meaning is the same if int is not mentioned. IMHO, MAX is a constant expression. Since its type is unspecified, it is an int. Since it is not specified as unsigned, and is an integral type, it is therefore a signed type. Together the conclusion that MAX is a "const signed int MAX" when all the defaults are considered. K&R say nothing about the issue of long or short. Neither does section A7.4.5 on the unary minus operator. The issue of long or short is probably best resolved in the traditional manner i.e. an integer is the size of the native machine word. This is 32 bits on a 68K. A 8086 or 286 would be 16 bits by the same tradition. The native int on the 68K is then a long int, and on the Intel it is a short int. The expectation that short int means 16 bits and long int means 32 bits is still meaningful. The answer to the question is machine architecture dependent. For purposes of the discussion at hand, the 68K compiler should treat MAX as a signed 32 bit integer. #Eric #ericco@ssl.berkeley.edu # -- Mark C. Edwards voice: 619/586-2204 Associate Systems Analyst unix: mce@pbsdts.pacbell.com Matt 3:16-17,Acts 7:55-56,*John 8:17-18,*John 14:28,*Mark 13:32, *John 20:17,*Matt 12:31-32,*John 17:20-23 (* Red letters)
mroberts@oracle.oracle.com (Mike Roberts) (03/03/90)
In article <8098@sdcc6.ucsd.edu> mce@sdcc10.ucsd.edu (Mark Edwards) writes: > [...example and much discussion deleted...] >#Like I said "MAX is not a number, its an expression." There is an integer >#in the expression (the number 32768). But there is also an operator (the >#unary minus). This makes MAX an expression, not a number. Thus the real >#question is what does K&R say integer expression are evaluated to? I >#don't have K&R handy, but I believe it says long ints. ># > [...more discussion deleted...] >IMHO, MAX is a constant expression. Since its type is unspecified, it is an >int. Since it is not specified as unsigned, and is an integral type, it is >therefore a signed type. Together the conclusion that MAX is a >"const signed int MAX" when all the defaults are considered. > [...yet more deleted...] The ANSI C draft, section 3.1.3.2 "Integer constants," says that type of an unsuffixed integer constant (i.e., no "L" or "U" suffix) is the first type from the following list big enough to hold the constant: int, long int, unsigned long int. I don't know how Turbo implements int on a 68k; the "natural" word size of a 68k is somewhat ambiguous, since the processor handles 16- and 32-bit computations equally well. If Turbo uses 16-bit int's, 32768 is promoted to long because it does not fit in an int; the "-" operator is then applied to the long, which results in a long. If Turbo uses 32-bit int's, 32768 fits in an int and no promotion takes place; applying the "-" operator does not result in any promotion, either, since, when it is applied to an int, and int results (see the draft, section 3.2 and 3.3).