[comp.sys.atari.st] Bug in TURBO-C V1.0

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).