Run time error (#define) challeng !!
Author Message
Run time error (#define) challeng !!

-----------------------

Hi, I have declared this

#define x  0x60000L
#define y    0x4000
#define z    ((y * 2) + x)

the value for z should be 0x68000 but the compiler generated 0x58000 !! why

Sun, 03 Sep 2000 03:00:00 GMT
Run time error (#define) challeng !!

I've run this using Borland C++ 5.01 and Symantec C++ 7.5.  I get 68000 both
times.  Here is the code I used:

/* TEST.C */
#include <stdio.h>
#define x 0x60000L
#define y 0x4000
#define z ((y * 2) + x)
int main()
{
printf( "%lx\n", z );
return 0;

Quote:
}

>-----------------------

>Hi, I have declared this

> #define x  0x60000L
> #define y    0x4000
> #define z    ((y * 2) + x)

>the value for z should be 0x68000 but the compiler generated 0x58000 !! why

Sun, 03 Sep 2000 03:00:00 GMT
Run time error (#define) challeng !!

Quote:

> Please email if you can
> -----------------------

> Hi, I have declared this

>  #define x  0x60000L
>  #define y    0x4000
>  #define z    ((y * 2) + x)

> the value for z should be 0x68000 but the compiler generated 0x58000 !! why

You probably have 16 bit ints or some such.  The expression 'y * 2' while
it looks correct probably yields the answer of 0x8000, which is a negative
number in a 16 bit system.  When expanded to 'long' width to be added with
the 'x' value (which is long), it turns into a negative number,
0x58000.

Solutions that MIGHT work:
#define y 0x4000L   /* make the multiply work in 'long' precision */
-or-
#define z    ((y * 2L) + x)   /* Force the other operand of the multiply to be
a long */
-or-
(both of the above)
-or-
#define z    (x + (y * 2))    /* Might work if compiler realizes that expression
starts out being a long.  Very iffy!! */
-or-
#define z    (((long)y * 2) + x)  /* Cast forcing */

The problem revolves around undetected overflow and the limits of
arithmetic.  Since the expression is constructed with the preprocessor,
and the final expansion is ALL constants, it is most likely a compiler
issue (no runtime involved).  Of course, compilers vary, and so will your
mileage.

--

Sun, 03 Sep 2000 03:00:00 GMT
Run time error (#define) challeng !!

Quote:

>-----------------------

>Hi, I have declared this

> #define x  0x60000L
> #define y    0x4000
> #define z    ((y * 2) + x)

>the value for z should be 0x68000 but the compiler generated 0x58000 !! why

First of all, after preprocessing, your expression looks like this:

(0x4000 * 2) + 0x60000L)

The constant 0x4000 fits into the range of an int, so it acquires that type.
However, multiplying 0x4000 by 2 (2 itself being type int) produces the value
0x8000, or 32768, which does not necessarily fit into the type int!  The type
int is required to only cover the range -32767 to 32767.  Many C
implementations provide a larger range, but implementations with 16 bit ints
are still around.

What happens when you overflow the range of an int is undefined behavior;
anything may happen. Some expected result may be produced, or some unexpected
result may be produced, or your program (or entire machine) may crash.

It would appear that your machine uses twos complement arithmetic, and
that it treats overflows by simply ``wrapping around'', so that the out of
range result 32768 (one higher than the highest integer) actually becomes
-32768 (the lowest integer) or -0x8000. Adding -0x8000 to the long int value

To produce the expected answer, you must ensure that the multiplication by
2 takes place using long integer arithmetic. To do this, you must ensure
that at least one of the two operands has type long, by adding the suffix
with which you appear to be already familiar:

(0x4000L * 2) + 0x60000L

Sun, 03 Sep 2000 03:00:00 GMT
Run time error (#define) challeng !!

Quote:

>-----------------------

>Hi, I have declared this

> #define x  0x60000L
> #define y    0x4000
> #define z    ((y * 2) + x)

>the value for z should be 0x68000 but the compiler generated 0x58000 !! why

Sure looks like a homework problem to me.
Hint: on the platform in question,
sizeof(int) != sizeof(long)
CHAR_BIT == 8
sizeof(int) == 2

A value of 0x58000 for z is not unexpected, on this platform, but the
result is not portable.  If I cared enough about non-portable
constructs, I would examine the standard to figure out whether 0x58000
is the required result or whether the result is formally undefined.
--

Kenan Systems Corporation

Sun, 03 Sep 2000 03:00:00 GMT
Run time error (#define) challeng !!

|
|-----------------------
|
|Hi, I have declared this
|
| #define x  0x60000L
| #define y    0x4000
| #define z    ((y * 2) + x)
|
|the value for z should be 0x68000 but the compiler generated 0x58000 !! why

Because you are using a compiler with 16-bit ints and
y*2 is interpreted as a 16-bit int expression.

z "should be" 0x68000 if you
#define y 0x4000L

Sun, 03 Sep 2000 03:00:00 GMT
Run time error (#define) challeng !!

: Please email if you can
: -----------------------

: Hi, I have declared this

:  #define x  0x60000L
:  #define y    0x4000
:  #define z    ((y * 2) + x)

: the value for z should be 0x68000 but the compiler generated 0x58000 !! why

You're hitting differences between sizeof(int) and sizeof(long).  Work it
out by hand using modulo 16-bit and 32-bit arithmetic.

Will

Sun, 03 Sep 2000 03:00:00 GMT
Run time error (#define) challeng !!

Groovy hepcat Charles LaCour was jivin' on Wed, 18 Mar 1998 18:17:14
GMT in comp.lang.c.
Re: Run time error (#define) challeng !!'s a cool scene! Dig it!

Quote:
>I've run this using Borland C++ 5.01 and Symantec C++ 7.5.  I get 68000 both
>times.  Here is the code I used:

>/* TEST.C */
>#include <stdio.h>
>#define x 0x60000L
>#define y 0x4000
>#define z ((y * 2) + x)
>int main()
>{
>   printf( "%lx\n", z );
>   return 0;
>}

I got 0x58000 with Watcom in 16 bit DOS, and 0x68000 in protected
mode. I added the L type modifier to the 0x4000 to make that line

#define y 0x4000L

and then I got 0x68000 in 16 bit DOS.

----- Dig the EVEN NEWER, MORE IMPROVED news sig!! -----

-------------- Shaggy was here! ---------------
http://aardvark.apana.org.au/~phaywood/
============= Ain't I'm a dawg!! ==============

Sun, 17 Sep 2000 03:00:00 GMT

 Page 1 of 1 [ 8 post ]

Relevant Pages