Article View: comp.std.c
Article #4014Re: EXIT_FAILURE problem
From: Jeremy Fitzhardinge
Date: Mon, 18 Sep 1995 11:09
Date: Mon, 18 Sep 1995 11:09
132 lines
5627 bytes
5627 bytes
In <1995Sep13.201030.20883@forte.com> mikes@forte.com (Mike Schilling) writes:
>: This is getting pretty silly. Why have the standard define something
>: completely undefined? It would be impossible for a conforming program
>: to use such a sys_exit() without knowing what OS_RET_TYPE is, which
>: means it can't be used unless a specific OS is targeted, which means it
>: would be non-portable. There's no point in having the standard define
>: a feature which can't be used portably.
>
>What is the purpose of a standard? If it's purely to distinguish
>conforming from non-conforming implementations, then this *is* useless;
>no test could determine whether it's implemented in a conforming way or not.
The C standard defines a language in which it is possible to write
programs. If a program has been written to conform to the rules of the
standard, then an implementation which also conforms to the standard
will be able to execute it. The standard is a contract between
programs and implementations.
If the standard makes a promise, an implementation must be able to make
good that promise for it to be any use to a programmer trying to use the
standard.
>Suppose, on the other hand, it's to help people write portable programs.
>It's unavoidable that portable programs will sometimes need to use
>system-specific services.
Quite, but it isn't the *C* language's role to define an interface for
system-specific services. C itself is extensible - you can add new
library functions without impinging on the standard's domain, which
means it's easy to build other standards on top of C; Posix for
example.
If you're writing code which you expect to run on a large variety of
systems, then you can make no assumptions about magic exit states at
all. If you do want to have magic exit states on lots of different
targets, you're going to have to have some target-specific code
anyway. What's the difference between:
/* Use OS specific exit() to return special state */
void magic_exit(struct status x)
{
#ifdef OS_1
sys$exit_magic(x.foo);
#elif OS_2
__sys_exit(x.bar);
#elif OS_3
extern void *_status;
extern jmpbuf __exitpoint;
static char buf[42];
sprintf(buf, "%08x", x.bibble);
_status = (void *)buf;
longjmp(__exitpoint, 23); /* 23 == 0 filled hex number */
#elif OS_4
kill(getpid(), SIGSEGV);
#else
#error "You're going to do something special here"
#endif
}
and
/* Try and use "standard" technique */
void magic_exit(struct status x)
{
#ifdef OS_1
OS_RET_TYPE s = s.foo;
#elif OS_2
OS_RET_TYPE s = s.bar;
#elif OS_3
/* Standard mechanism can't cope with this */
#error "Need to use the Fooboz Co. longjmp to get dynamic type to environment"
#elif OS_4
/* Nor this */
#error "Want to make a core"
#else
#error "You're going to do something special here"
#endif
sys_exit(s);
}
?
Nothing, except the "standard" non-portable interface is no easier to use
and less useful.
> The best way (IMHO) to do this is to create
>a portable abstraction and implement that abstraction on the target
>platforms. I'm suggesting as portable an abstraction as possible, and
>suggesting that the compiler vendor implement it.
Cool idea. OK, programs have to be able to terminate, and it would be
nice to communicate to their environment whether they feel they
succeeded or not. While fooblatz OS here allows us to return an FP
number between 0 and 4.3 to determine a degree, and GungeOS there lets
us return "fail", "poor", "fair", "pass" and "credit", it would be
better to just stick with "it worked" or "it didn't". If a GungeOS
program really wants to exit with credit, it can call "GungeExit()",
no?. To make it easy we could call these values "EXIT_SUCCESS" and
"EXIT_FAILURE", but since we have quite a lot of code which uses (int)0
for "success" and !0 for failure, we'll allow that too.
How about it?
> The alternative is
>for each user who needs it to implement it, which requires digging into the
>internals of each implementation of 'exit' to try to separate the portable
>part (closing files, calling atexit functions, etc.), which is still
>required, from the non-portable part (returning status to the OS),
>which needs to be replaced.
You could consider it a flaw of your implementation if it has a non-standard
way of exiting without providing any way of performing standard cleanup
functions.
>Yes, the use of sys_exit would have to be ifdef'd (or put in a system-
>specific file) but it would be far more convenient for a developer
>porting to a new system to code the proper variant of the sys_exit
>call than to investigate the C exit implementation and the OS system
>call which exits, and then decide how to combine the two. Isn't
>making life easier for developers the purpose of language standards?
Surely it would be better to just define:
/* Clean up the library before exit - no standard library functions may
be called after calling this, nor can you return from main() */
void exit_cleanup(void);
It would be well defined, easy to implement, and allow any way of
terminating whatever. It itself could be used portably, but not by any
conforming program.
J
Technical Details
Message-ID:
<jeremy.811422543@suede.sw.oz.au>Path:
arc1-ca.pugleaf.net!swallow.sw.oz.au!jeremyReferences:
<jeremy.810996048@suede.sw.oz.au> <1995Sep13.201030.20883@forte.com>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!swallow.sw.oz.au!jeremy From: jeremy@sw.oz.au (Jeremy Fitzhardinge) Newsgroups: comp.std.c Subject: Re: EXIT_FAILURE problem Date: 18 Sep 95 11:09:03 GMT Organization: Softway Pty Limited Message-ID: <jeremy.811422543@suede.sw.oz.au> References: <jeremy.810996048@suede.sw.oz.au> <1995Sep13.201030.20883@forte.com> NNTP-Posting-Host: suede.sw.oz.au