Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 May 1996 20:19:48 +0100
From:      "Gary Palmer" <gpalmer@FreeBSD.ORG>
To:        hackers@FreeBSD.ORG
Cc:        scrappy@ki.net
Subject:   I HATE OPTIMISING COMPILERS
Message-ID:  <13116.833311188@palmer.demon.co.uk>

next in thread | raw e-mail | index | archive | help

Well, I certainly do at the minute.

Take the following innocuous piece of code:

    if (pdu->version == SNMP_DEFAULT_VERSION)
	pdu->version = session->version;

    if (pdu->version == SNMP_DEFAULT_VERSION){
	fprintf(stderr, "No version specified\n");
	snmp_errno = SNMPERR_BAD_ADDRESS;
	return 0;
    }

Looks fine, right?

Sorry, you lose (and so did I, well over an hour of time tracking down
this damned problem).

Every time you run that piece of code, you get "No version specified".
So I go and stick in a nice printf just above the first if statement
to check that it's not doing something funny. The code now becomes:

    printf("pdu->version = %d\nsession->version = %d\nSNMP_DEFAULT_VERSION = %d\n",
	   pdu->version, session->version, SNMP_DEFAULT_VERSION);

    if (pdu->version == SNMP_DEFAULT_VERSION)
	pdu->version = session->version;

    if (pdu->version == SNMP_DEFAULT_VERSION){
	fprintf(stderr, "No version specified\n");
	snmp_errno = SNMPERR_BAD_ADDRESS;
	return 0;
    }

Which produces:

pdu->version = -1
session->version = 2
SNMP_DEFAULT_VERSION = -1
No version specified

So, okay, session->version != SNMP_DEFAULT_VERSION, but the problem is
the aggregate of those two if statements disagrees. Hmm. Okay. Put in
a second printf:

    printf("pdu->version = %d\nsession->version = %d\nSNMP_DEFAULT_VERSION = %d\n",
	   pdu->version, session->version, SNMP_DEFAULT_VERSION);

    if (pdu->version == SNMP_DEFAULT_VERSION)
	pdu->version = session->version;
 
    printf("pdu->version = %d\nsession->version = %d\nSNMP_DEFAULT_VERSION = %d\n",
	   pdu->version, session->version, SNMP_DEFAULT_VERSION);

    if (pdu->version == SNMP_DEFAULT_VERSION){
	fprintf(stderr, "No version specified\n");
	snmp_errno = SNMPERR_BAD_ADDRESS;
	return 0;
    }

And all of a sudden IT STARTS WORKING PROPERLY. Take out the two
printfs, a nasty idea forming in my mind. The code now becomes:

    if (pdu->version == SNMP_DEFAULT_VERSION)
	pdu->version = session->version;

    session->version = pdu->version;

    if (pdu->version == SNMP_DEFAULT_VERSION){
	fprintf(stderr, "No version specified\n");
	snmp_errno = SNMPERR_BAD_ADDRESS;
	return 0;
    }

Which looks kinda daft, but again, the code worked as expected. Take
out the ``session->version = pdu->version;'' statement, and it starts
failing again. Now I'm really suspicious. Go to the Makefile. Change
``CFLAGS=-O -g -Dfreebsd2'' to be just ``CFLAGS=-Dfreebsd2''. make
clean all. Go and rebuild the client apps that depend on the
library.

BINGO. Much cheering and celebrating. I go to the fridge and get
another coke.

Anyone want to help me take GCC out the back kicking and screaming to
face the shooting squad? Admittedly that code isn't the most elegant
way of doing that assignment/test, but GCC should NOT produce such
bogus code from it :-( And here we (or at least I) thought that `-O'
was safe to use :-(

``Sigh.''

Gary
--
Gary Palmer                                          FreeBSD Core Team Member
FreeBSD: Turning PC's into workstations. See http://www.FreeBSD.ORG/ for info



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?13116.833311188>