Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 May 2015 02:43:06 +1000 (EST)
From:      Ian Smith <smithi@nimnet.asn.au>
To:        andrew clarke <mail@ozzmosis.com>
Cc:        freebsd-questions@freebsd.org, Trev Roydhouse <trev@sentry.org>
Subject:   Re: Strange return codes from old but good C program
Message-ID:  <20150517232103.V69409@sola.nimnet.asn.au>
In-Reply-To: <20150517124223.GA82704@ozzmosis.com>
References:  <20150517204503.V69409@sola.nimnet.asn.au> <20150517124223.GA82704@ozzmosis.com>

Next in thread | Previous in thread | Raw E-Mail | Index | Archive | Help
On Sun, 17 May 2015 22:42:24 +1000, andrew clarke wrote:
 > On Sun 2015-05-17 22:16:14 UTC+1000, Ian Smith (smithi@nimnet.asn.au) wrote:
 > 
 > > Hi,
 > > 
 > > I'm hoping someone can help me figure out the behaviour of a C program 
 > > executed repeatedly from a shell invoked by my freepascal program.
 > > 
 > > If anyone might care to download <http://www.moshier.net/de118i-2.zip>; 
 > > (258071 bytes), unzip it and run 'make', the supplied makefile - a copy 
 > > of unixl.mak - should provide ssystem compiled for long double precision 
 > > maths, just as I wanted, with the following output from gcc from FreeBSD 
 > > 4.5 to 9.3-RELEASE.  (If clang has trouble on 10.X, please let me know)
 > 
 > That makefile defaults to gcc but allows you to build it with clang
 > (which spits out a bunch of warnings similar to gcc) using:
 > 
 > make -f unixl.mak CC=clang

Thanks, trying that on 9.3 .. ooo yes, lots of warnings until adding 
#include <stdlib.h> to the #ifdef UNIX section, as you say.  Remaining 
are only warnings for a number of functions like:
ssystem.c:171:1: warning: type specifier missing, defaults to 'int' 
 [-Wimplicit-int]
main()
^~~~
ssystem.c:456:1: warning: type specifier missing, defaults to 'int' 
 [-Wimplicit-int]
func( t, yin, v )
^~~~
ssystem.c:607:1: warning: control reaches end of non-void function 
 [-Wreturn-type]
}
^

 > > smithi@x200:~/de118i-2 % make
 > > gcc -O2 -c ssystem.c
 > > ssystem.c: In function 'resstate':
 > > ssystem.c:150: warning: incompatible implicit declaration of built-in 
 > >  function 'exit'
 > > ssystem.c: In function 'main':
 > > ssystem.c:180: warning: incompatible implicit declaration of built-in 
 > >  function 'malloc'
 > 
 > stdlib.h provides prototypes for exit() and malloc().
 >
 > #include <stdlib.h>

They're not declared or overloaded anywhere that I can see but did work?

 > > ssystem runs as well as ever, these warnings indicate no functional 
 > > issues, but they do highlight the author's poor (but unsurprising in 
 > > 1993, last updated 2004) choice of return codes both for real errors 
 > > (malloc, file I/O, and maths div by zero, bad args for trig functions 
 > > and such) which mostly exit(1) but some return 0 (!) - but when ending 
 > > successfully it returns _usually_ 22, but sometimes 11, or 10, both seen 
 > > so far, consistently when run with the same (different) parameters.
 > 
 > The code looks like ancient K&R C, which was a lot more relaxed with
 > syntax than modern ISO C compilers. Even by 1993, most C developers
 > had moved on from K&R.

If you check moshier.net, Steve's written heaps of stuff, advanced maths 
libraries and lots more but I gather he's more a C user than developer.

 > > What's worse is I can't figure out where in ssystem.c any return code 
 > > might be set on completion of main(), which is just declared as:
 > > 
 > > main()
 > > {
 > 
 > This is fine in K&R, but the ISO C prototype for main() without arguments is:
 > 
 > int main(void);

C is read-only for me, but that's what I've come to expect seeing.

 > > and ends with the last of its results and (accuracy) errors printf()s:
 > > 
 > >         ii += 6;
 > >         }
 > > #if FPESHOW	# floating point debug, here set to 0
 > > fperem();
 > > #endif
 > > } /* end of main program */
 > > 
 > > No variables called rc or anysuch .. so what sets these odd retcodes?
 > 
 > Normally you'd use a return statement, eg.
 > 
 > #include <stdio.h>             /* prototype for printf() */
 > 
 > int main(void)
 > {
 >     printf("Hello world.\n");  /* say hi */
 > 
 >     return 0;                  /* return zero to the OS */
 > }
 > 
 > I haven't checked the standard but it's plausible that the ISO C spec
 > allows a random return code if none is given, especially if no
 > prototype for main() is provided.

Fair enough, but it doesn't seem properly random.  Same parameters, same 
result.  Different parameters nearly always give the same result, but 
not always.  It could be an otherwise uninitialised value somewhere, but 
why half of that sometimes?  Or 10 (seen only on amd64 here)?

Have you tried running 'ssystem <test.que >test.ans' to compare test.ans 
with test.ld?  Ahah, that's just where I spotted those 10 and 11 values:

smithi@x200:~/de118i-2 % ssystem < test.que > test.ans ; echo $?
10

# above on amd64 (same result when built with clang), but on i386:

smithi on t23% ssystem < test.que > test.ans ; echo $?
11

Worse, NO other input parameters in *.que that I try, WON'T return 22 :)

Instead of fixing the declaration and adding return 0, would exit(N) do?

 > There may be tools around to convert K&R C code to ANSI/ISO C syntax,
 > rather than trying to do it by hand. The code may still need some
 > tweaking, though, eg. return 0 from main().

This code has been used in some pretty high-powered long-term ephemeris 
production - patches with 128-bit 'long long doubles' that purport to 
track (eg) earth's eccentricity back ~1M years - so I'm loathe to mess 
with it unless necessary.  If I were going to touch it for porting I'd 
need to clean up eg the errors like malloc and failure to find a needed 
file, that now return 0 (!) also.

If I could feel confident that success would never return 0 or 1 - the 
case so far, over many runs recently - then I needn't worry.  As is, I 
loudly report any non-22 retcodes, so if it ever did return 0 or 1 then 
at least the (perhaps many hours long) run would stop with that report, 
so it's not bad in the worst case, but still I can't help wonder, why?

 > > I'd be grateful for any clue.  So far I assume any return code > 1 is 
 > > success, so far so good - but it doesn't feel deterministic enough :)
 > > 
 > > cheers, Ian  (please cc me, I'm subscribed to the digest)
 > 
 > Pretty sure I know you from FidoNet, years ago. Also Trev Roydhouse.
 > AUST_C_HERE, or another echo, maybe?

Indeed, I've wondered about that myself.  Ah, those were the days .. :) 
I'll reply privately re all that, but not tonight.

Thanks for help and encouragement Andrew,

cheers, Ian



Want to link to this message? Use this URL: <http://docs.FreeBSD.org/cgi/mid.cgi?20150517232103.V69409>