🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by George Jetson Fri, 09 Oct 1992 18:22
Incorrect code generated unless optimization is turned on.
#1182
Author: George Jetson
Date: Fri, 09 Oct 1992 18:22
102 lines
3378 bytes
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));
}
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads