[comp.lang.c] compiler detecting divide by zero

ts@cup.portal.com (Tim W Smith) (11/26/90)

For obscure reasons that I won't go into, I wanted a divide
by zero in a program.  I was compiling on SCO Unix System V/386
relase 2.2 (I think...) with whatever C compiler comes with
this version of Unix.

I tried the obvious:

	int	i, j;

	i = 1;
	j = 0;
	i/=j;

The compiler caught this.  Grrr.  Next I tried:

	i = 1;
	j = 1;
	i -= 1;
	j/=i;

It still caught it.  Double grrr!

Next try:

	int	i, j, *p;

	i = 1;
	j = 1;
	p = &i;
	j /= *p - 1;

It still caught it!

This one got past it:

	j = 5;
	for ( i = 0; i < 5; i++ )
		j--;
	i /= j;

After the previous try, I was a bit surprised that it didn't
figure out this one!

						Tim Smith

lerman@stpstn.UUCP (Ken Lerman) (11/27/90)

In article <36233@cup.portal.com> ts@cup.portal.com (Tim W Smith) writes:
->For obscure reasons that I won't go into, I wanted a divide
->by zero in a program.  I was compiling on SCO Unix System V/386
->relase 2.2 (I think...) with whatever C compiler comes with
->this version of Unix.
->
->I tried the obvious:
->
->	int	i, j;
->
->	i = 1;
->	j = 0;
->	i/=j;
->
->The compiler caught this.  Grrr.  Next I tried:
->
->	i = 1;
->	j = 1;
->	i -= 1;
->	j/=i;
->
->It still caught it.  Double grrr!
->
->Next try:
->
->	int	i, j, *p;
->
->	i = 1;
->	j = 1;
->	p = &i;
->	j /= *p - 1;
->
->It still caught it!
->
->This one got past it:
->
->	j = 5;
->	for ( i = 0; i < 5; i++ )
->		j--;
->	i /= j;
->
->After the previous try, I was a bit surprised that it didn't
->figure out this one!
->
->						Tim Smith

I haven't tried it, but I'll bet that:

    int divide(int a, int b){ return a/b; }

will cause your divide error when called by:

    x = divide(1,0);

Of course, if your compiler is brilliant, you might have to put the
function divide in a separate file. :-)

Ken

grogers@convex.com (Geoffrey Rogers) (11/28/90)

In article <36233@cup.portal.com> ts@cup.portal.com (Tim W Smith) writes:
>I tried the obvious:
>
>	int	i, j;
>
>	i = 1;
>	j = 0;
>	i/=j;
>

Most compilers today do constant folding and propogration on either
a local or global (with the entire function) optimization. This is
what you are getting bitting by.

>This one got past it:
>
>	j = 5;
>	for ( i = 0; i < 5; i++ )
>		j--;
>	i /= j;
>

The best way I found to get around this problem is by doing:

	div(0,1)
	...

	div(a,b)
		int a,b;
	{
		a = b/a;
	}

This will work for almost all compilers (expect compilers that can
do interprocedural optimizations, which there are not many). The
only time I have done something like this is for testing.

+------------------------------------+---------------------------------+
| Geoffrey C. Rogers   		     | "Whose brain did you get?"      |
| grogers@convex.com                 | "Abbie Normal!"                 |
| {sun,uunet,uiucdcs}!convex!grogers |                                 |
+------------------------------------+---------------------------------+

userAKDU@mts.ucs.UAlberta.CA (Al Dunbar) (11/29/90)

In article <36233@cup.portal.com>, ts@cup.portal.com (Tim W Smith) writes:
>For obscure reasons that I won't go into, I wanted a divide
>by zero in a program.  I was compiling on SCO Unix System V/386
>relase 2.2 (I think...) with whatever C compiler comes with
>this version of Unix.
>
>I tried the obvious:
>
>        int     i, j;
>
>        i = 1;
>        j = 0;
>        i/=j;
>
>The compiler caught this.  Grrr.  Next I tried:
 
I was curious about how my compiler would handle these
attempts (QC 2.51), so I tried it, and it caught them
all! Next I tried:
 
scanf( "%d %d", i, j );
i/=j
 
Would you believe it caught this too ("Warning: user may
accidentally enter invalid input resulting in a runtime
divide exception")?
 
 
 
 
 
I didn't think so :-)
 
-------------------+-------------------------------------------
Al Dunbar          |
Edmonton, Alberta  |  "this mind left intentionally blank"
CANADA             |          - Manuel Writer
-------------------+-------------------------------------------
#! r

chris@mimsy.umd.edu (Chris Torek) (11/29/90)

In article <5857@stpstn.UUCP> lerman@stpstn.UUCP (Ken Lerman) writes:
>I haven't tried it, but I'll bet that:
>    int divide(int a, int b){ return a/b; }
>will cause your divide error when called by:
>    x = divide(1,0);
>Of course, if your compiler is brilliant, you might have to put the
>function divide in a separate file. :-)

Even that is unlikely to help for long.  (You can expect better IBM PC
compilers to do cross-module optimization within 5 years.  [I actually
expect it sooner than this.  MIPS and Sun already do it.])

Here is something that *will* (must) work:

	const volatile int zero = 0;
	int exception = 1 / zero;

A compiler cannot assume that a `const volatile int' has any particular
value.  For instance:

	extern const volatile int clock;	/* mapped by linker to clock */

might tell you the current time in seconds since the machine was booted.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

djones@megatest.UUCP (Dave Jones) (12/04/90)

From article <36233@cup.portal.com>, by ts@cup.portal.com (Tim W Smith):
> For obscure reasons that I won't go into, I wanted a divide
> by zero in a program.

[But the compiler made it tough.]

I too got into a mess like this the other day. I was writing some
very low-level stuff and just wanted to use the assembly language output
from the C compiler as a guide. The compiler "optimized" away some of
my code. It didn't optimize away all of it, although it was all theoretically
"dead".  Luckily, checking it over, I figured out that something
was amiss.