ftp.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1992/10/09/14:53:21

Date: Fri, 9 Oct 92 13:22:33 CDT
From: "George Jetson" <pynq AT midway DOT uchicago DOT edu>
To: bug-gcc AT prep DOT ai DOT mit DOT edu
Subject: Incorrect code generated unless optimization is turned on.
Cc: djgpp AT sun DOT soe DOT clarkson DOT edu

Short synopsis: I am running DJGPP 1.08, under MS/DOS.  gcc -v reports 2.2.2.
Unfortunately, I do not have access to a 386 version of Unix to test this on.
I did nothing other to unpack the .ZIP files and run them (no compiler mods)

The following program generates an exception 13 error when compiled
normally; when compiled with either -O or -O2, it works fine.
I spent some time running through it with DEBUG32, and found:

	1) The problem is in function big_cmp.
	2) Some register (either eax or edx, depending on which exact
	   version of the source code you use) is used as the address of
	   the local variable i and it gets trashed during the loop, so
	   that on the second run through the loop, the address is invalid.

This was compiled with all of the following commands, then run via "GO32 a.out".
(Only the first, with no optimization, causes the error)

	1) gcc -Wall -Werror qs1.c
	2) gcc -O -Wall -Werror qs1.c
	3) gcc -O2 -Wall -Werror qs1.c

---- Cut here ---

#ifndef __GNUC__
#error "Please use DJGPP!"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <stdarg.h>
#include <ctype.h>
#include <limits.h>

/* This is my version of the "missing" strnicmp() */
int Strnicmp(const char *s1, const char *s2, int count)
{
	int res;

        for (res = 0; count &&
                !(res = tolower(*s1) - tolower(*s2)) && *s1 && *s2;
                s1++, s2++, count--);
	return (res);
}

void main()
    {
    int numlines = 1,numthings = 2,nkeys = 2;
    struct key {
	int lexical,direction,line,offset,width;
	} keys[nkeys];
    struct thing {
	int recnum;
	char *text[numlines+1];
	int textlen[numlines];
	} things[numthings];
    int big_cmp(struct thing *t1, struct thing *t2)
	{
	int i,res;

	for (i=0; i<nkeys; i++) {
	    int ln = keys[i].line;
	    int off = keys[i].offset;
	    char *s1 = t1 -> textlen[ln] > off ? t1 -> text[ln] + off : "";
	    char *s2 = t2 -> textlen[ln] > off ? t2 -> text[ln] + off : "";
	    int w = keys[i].width;

	    if (res = keys[i].direction *
		(keys[i].lexical ? (Strnicmp(s1,s2,w) ? : strncmp(s1,s2,w)) :
		 strncmp(s1,s2,w)))
			return (res);
	    }
	return (t1 -> recnum - t2 -> recnum);
	}

    keys[0].lexical = 0;
    keys[0].direction = 1;
    keys[0].line = 0;
    keys[0].offset = 0;
    keys[0].width = 5;

    keys[1].lexical = 0;
    keys[1].direction = 1;
    keys[1].line = 0;
    keys[1].offset = 10;
    keys[1].width = 5;

    things[0].recnum = 0;
    things[0].text[0] = "This is the first line";
    things[0].text[1] = 0;
    things[0].textlen[0] = 22;

    things[1].recnum = 1;
    things[1].text[0] = "This is the second line";
    things[1].text[1] = 0;
    things[1].textlen[0] = 23;

    printf("Here we are...");
    printf("The result is %d\n",big_cmp(things,things + 1));
}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019