[comp.std.c] More thoughts on "Error Return"

iiitsh@cybaswan.UUCP (Steve Hosgood) (08/09/89)

Netreaders will remember my original article a week or so ago that discussed
adding the ability for C functions to return unambiguous error
indications without all the problems currently encountered. I've been well
pleased with the replies I've read. Below are my answers to some of the
comments I've seen.

> From: pardo@june.cs.washington.edu (David Keppel)
> Date: 4 Aug 89 17:09:21 GMT
> Organization: University of Washington, Computer Science, Seattle
> Lines: 16
> 
> iiitsh@cybaswan.UUCP (Steve Hosgood) writes:
> >[errval(foo())]
> 
> Until it is `prior art', it probably doesn't belong in dpANS C.
> 
> Often, `-1' is used as a return value for things that can be array
> indicies, because `-1' can't be an array index.  Having `errval'
> requires that you know not just the return type, but also which kinds
> of values are going to be meaningful (since, e.g., not all compilers
> have condition codes).  To do this `right', you need a stronger typing
> system than C provides.
> 

My 'errval' macro that checks for 'x < 0' or possibly 'x == 1' was intended as
a way for users with older compilers without the proposed feature to 'fake' it
fairly easily. Obviously, you have no type-checking with a macro, and you're
reliant on the actual return value to tell you there's an error, so the macro
you use will often have to be tailored to the function that you called.
'Errval' (or whatever) *must* be implemented by the compiler so as to work
properly.

> From: siebren@piring.cwi.nl (Siebren van der Zee)
> From: david@psitech.UUCP (david Fridley)
> Date: 5 Aug 89 20:41:45 GMT
> Organization: PsiTech Inc., Fountain Valley, CA
> 
> Wouldn't it be nice if you could return more than one value from a C function?
> ie:
> 	(ret1,ret2)=func(param1,param2,param3);
> I believe this would solve error problems, and many others that I have had.
>

I've often though about this, but can't think up a sensible methodology. The
idea of passing a boolean WIN/LOSE flag along with the normal return value is
managable (I think), let's see if anyone out there can come up with a multiple
return value scenario. Oh, and don't use a comma to seperate the multiple
targets of the assignment - comma is already used for other things, and we
can't have a context sensitive grammar! See later.

> Date: 4 Aug 89 19:40:24 GMT
> Organization: CWI, Amsterdam
> 
> Ok, and now the hard part: what should the code from the
> CALLED function look like?
> 

Oops, I left that out of the posting! Sorry. Actually, Henry Spencer's
posting and my reply just about answer this question - read on.

> From: henry@utzoo.uucp (Henry Spencer)
> Date: 5 Aug 89 22:33:31 GMT
> Organization: U of Toronto Zoology
> 
> In article <8314@boring.cwi.nl> siebren@piring.cwi.nl (Siebren van der Zee) writes:
> >>[errval(foo())]
> >Ok, and now the hard part: what should the code from the
> >CALLED function look like?
> 
> The obvious thing to do is to have two different kinds of "return" statement,
> one for normal and one for errors.  That completely hides how the "error"
> flag is passed back.  Unfortunately, it is awkward on some machines, where
> there are no condition codes.
> 

As I said above, I forgot to mention this bit in my posting. Two different
return statements would do the trick, but I'd rather see a way of passing
the 'error' flag from a variable. I'd like to see any extension involve the
least number of new reserved-words - this proposal requires 'ereturn' or
something similar to be reserved. Also, I consider it neater to have my
routines terminate in a single 'return' statement, and having to use two
differnt types of 'return' in order to pass the 'error' flag rather precludes
this.

So: maybe something like

	...
	return val, err;

..would do the trick. I don't seriously want to use a comma seperator though,
as it's already used for other things. Trouble is, I can't think of any
other unused seperator. The guy (see above) who proposed the more general
multiple value return mechanism used commas too. Better find another symbol.
Double colon might work - but I think that's used by C++ and that could cause
problems if 'C' started to employ it too.

Let's see:

	...
	return val::errflag;

..seen worse, though C++ boys will be hammering on the door any minute now!.
 
> Interested parties, note:  the idea is *guaranteed* to go nowhere unless
> you are interested enough to implement it in a compiler.
> -- 

..yeah, but if you implement such a concept in a compiler, you've just put
an extension into it, and that would start to undo all the standards effort
straight away. I hate 'extended' languages - DEC and HP are my least favorite
language vendors for this very reason. It's all a bit 'chicken and egg' if
ANSI won't consider it until someone implements it.

> From: mwm@eris.berkeley.edu (Mike (I'll think of something yet) Meyer)
> Date: 5 Aug 89 04:46:49 GMT
> Organization: Missionaria Phonibalonica
> 
> How about:
> 
> #define errval(x)	(errno = 0, (x), errno)
> 
> It'll even work on the current standard. Whether you can get this to
> turn into tweaks to the carry flag (I hope that nobody would advocate
> referring to hardware flags in the standard; there's already hardware
> that C runs on without such flags) in a standard-conforming compiler
> is an interesting question.
> 

I agree, the standards mustn't refer to the 'carry' flag. Chances are that
many implementors would use the carry flag though - if there is one on the
hardware.

> From: gregg@cbnewsc.ATT.COM (gregg.g.wonderly)
> Date: 6 Aug 89 22:38:46 GMT
> Organization: AT&T Bell Laboratories
> 
> I have always liked the idea of having the types of information that VMS
> provides in condition codes.

All I'm trying to suggest is a method for giving the caller of a C-routine
the information that a failure occurred. Once he knows that it failed he can
go find out the real reason. Often that will be to check the actual return
value, or possible the 'errno' external variable.

What Gregg's doing (I think) is proposing a more powerful 'errno' variable.
I *think* this a parallel thread. Redefining 'errno' requires no changes to
'C' - just a change in accepted procedure by the writer and users of standard
library routines. To be honest - I dislike the VMS approach... too heavy, man! 

> From: peter@ficc.uu.net (Peter da Silva)
> Date: 7 Aug 89 13:36:29 GMT
> Organization: Xenix Support, FICC
> 
> In article <26998@agate.BERKELEY.EDU>, mwm@eris.berkeley.edu (Mike (I'll think of something yet) Meyer) writes:
> > #define errval(x)	(errno = 0, (x), errno)
> 
> This is how you get programs that spit out messages like:
> 
> 	"peter@ficc.uu.net: Not a tty"
> 

IMHO, the error message quoted is due to sloppy programming rather than
an error-return mechanism. Some routine returned an error, it's just been
mis-interpreted.

Mind you, it's not *that* wrong either. You're *not* a tty are you Peter? :-)

-----------------------------------------------+------------------------------
Steve Hosgood BSc,                             | Phone (+44) 792 295213
Image Processing and Systems Engineer,         | Fax   (+44) 792 295532
Institute for Industrial Information Techology,| Telex 48149
Innovation Centre, University of Wales,        | JANET: iiitsh@uk.ac.swan.pyr
Swansea SA2 8PP                                | UUCP: ..!ukc!cybaswan!iiitsh
-----------------------------------------------+------------------------------
            My views are not necessarily those of my employers!
           Please note the change in my username as of 1 Aug '89

henry@utzoo.uucp (Henry Spencer) (08/11/89)

In article <601@cybaswan.UUCP> iiitsh@cybaswan.UUCP (Steve Hosgood) writes:
>> Interested parties, note:  the idea is *guaranteed* to go nowhere unless
>> you are interested enough to implement it in a compiler.
>
>..yeah, but if you implement such a concept in a compiler, you've just put
>an extension into it, and that would start to undo all the standards effort
>straight away. I hate 'extended' languages - DEC and HP are my least favorite
>language vendors for this very reason. It's all a bit 'chicken and egg' if
>ANSI won't consider it until someone implements it.

It is a sad fact that experimenting with extensions means experimenting with
a non-standard language.  You have to be convinced that it's worth it.  (I
personally don't see this as entirely a bad thing -- it cuts down on the
number of frivolous experimental extensions.  Note, "cuts down", as opposed
to "eliminates".)  But sane standards committees will indeed refuse to have
anything to do with an idea if it has not been tried in an implementation.
Language design is **MUCH** harder than it looks; the *only* way to be sure
that some wonderful new feature does not interact unpleasantly with existing
ones (and that it really is practical and useful) is to implement it and
use it in real programming.

(Note, not all standards committees are sane.  X3J11 did pretty well, on
the whole; they only had occasional moments of insanity.  You can pretty
much tell which moments those were, because the resulting features caught
orders of magnitude more flak from the customers.)
-- 
V7 /bin/mail source: 554 lines.|     Henry Spencer at U of Toronto Zoology
1989 X.400 specs: 2200+ pages. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

david@psitech.UUCP (david Fridley) (08/12/89)

I have a new idea, or at least half of one:

	func(..)
	{	:
		:
		if(err)
			return("func: there has been an error\n");
		else
			return(cptr);
	}

	main()
	{	tmp=func(..);
		if(tmp>_CODESEGMENTSTART && tmp <=CODESEGMENTEND)
		{	/* there has been an error */
		}
	}

Advantages: you do not need a global list of error code to figure out what
the error is.  New functions and libraries can implement their own errors
with out fear of confusing meaning with those of other functions/libraries.
The pointers will be valid, yet it will be possible to determine that they
are errors.. It may even be possible to put error messages
in their own seperate sections.

Disadvantages: Some compilers may put strings in the data segment, or not
even have segments?  Some functions may correctly return static strings
or pointers to functions. For these functions we won't be able to use this
method of error handeling.

The basic idea here is to let each module define it's own errors, to avoid
global variables (like errno), and to return an otherwise valid pointer
that can be determined to be an error with out specific knolege of the
errors returned by that function.

Standard changes: (The chicken and the egg story).

The reason that we have a C standard is so that we can write code that is 
portable between C compilers.  I can not write code that takes advantage
of one Company's extensions because it will not run on the other compilers
I use (The above Idea will work on all the compilers I use now, but remember
it is only half an Idea.).  Perhaps after ANSI is finally final (I had to
say it (why aren't nested ()'s allowed in English. Where is the English
standard committe so I can complain.)) they will be able to consider
additions of their own, because this will become the only way to make
changes to the language. Perhaps the partisipation of some number of complier
companys will be required in order to demonstrate it's fiesability, usefullness,
and desirability.

If we are going to make additions to C I propose that we make them as general
as possible (like returning multiple values from a function), rather than
specific (like returning one more value, or an error flag).
	(ret1,ret2...)=func(p1,p2...)
	{ret1,ret2,..}=func(p1,p2...)
The first one looks better to me than the second, but I am concerned about
function, not syntax.


-- 
david.
DISCLAIMER: If it's important have a backup.  If it ain't broke don't fix it.
Proceed at your own risk.  My oponions are MY own.  Spelling does not count.
My fondest dream is to leave this planet.