Run time error (#define) challeng !! 
Author Message
 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



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:
}

>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



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,
subtracting, not adding to the total.  The answer obtained is then
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:

>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

The answer rests in your fine language reference manual.

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
0x60000 produces 0x58000, which is your mysterious, incorrect answer.

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:

>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

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 !!

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

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  
 
 [ 8 post ] 

 Relevant Pages 

1. Run time Release mode error but no Debug mode error

2. Abnormal Program Termination Error -- MS C++ Run Time Library Error

3. Abnormal Program Termination Error -- MS C++ Run Time Library Error

4. Abnormal Program Termination Error -- MS C++ Run Time Library Error

5. Mathematical Function - defining at run-time??

6. Run-time type define

7. Function question Part 2 ( RUN TIME ERROR PROBLEM )

8. Run-time Error??!!

9. Specialised tool for run-time error detection

10. Run time error?!?!

11. Turbo C++ run time error

12. Invalid file format run-time error

 

 
Powered by phpBB® Forum Software