LWN.net Logo

Zeuthen: Writing a C library, part 1

Zeuthen: Writing a C library, part 1

Posted Jun 28, 2011 9:20 UTC (Tue) by gowen (guest, #23914)
In reply to: Zeuthen: Writing a C library, part 1 by dgm
Parent article: Zeuthen: Writing a C library, part 1

Returning error codes, and per thread error flags are nothing new. It has been standard practice for ages. It works, and is not that complicated.
I never suggested it was overly complicated, I was disagreeing with the assertion that it was the *most* simple. Almost everything else you say I am in agreement with.

Good engineering says "don't call abort()"


(Log in to post comments)

Zeuthen: Writing a C library, part 1

Posted Jun 28, 2011 10:16 UTC (Tue) by gevaerts (subscriber, #21521) [Link]

Did the original post say that though? I didn't read "Proper memory management is most expected, and easiest implemented, in libraries" as "memory management is easier than anything else" but rather as "memory management in libraries is easier than anywhere else"

Zeuthen: Writing a C library, part 1

Posted Jun 28, 2011 12:34 UTC (Tue) by gowen (guest, #23914) [Link]

That's a good point. I think its possible I mis-parsed the original posters intent, in which case I withdraw my argument about "easiest". But I do think that thread-local-errno is a horrible hack around C's limitations.

Zeuthen: Writing a C library, part 1

Posted Jun 28, 2011 13:31 UTC (Tue) by cmccabe (guest, #60281) [Link]

> But I do think that thread-local-errno is a horrible hack
> around C's limitations.

Then you'll be happy to hear that thread-local errno has been deprecated for decades now. New functions that are added to POSIX generally return an error code indicating the error instead.

errno has nothing to do with "C's limitations" and everything to do with preserving compatibility with an older interface that isn't worth the effort to change.

Returning error codes is a great convention because you can flag them with __attribute__((warn_unused)). Then the programmer will get a warning from the compiler unless he checks the return code.

Zeuthen: Writing a C library, part 1

Posted Jun 29, 2011 7:16 UTC (Wed) by gowen (guest, #23914) [Link]

Returning error codes is a great convention because you can flag them with __attribute__((warn_unused)). Then the programmer will get a warning from the compiler unless he checks the return code.
Returning error codes is fine in certain circumstances (particularly for functions where the side-effects are the point). Sometimes, though, you want your functions to be functions in the lambda-calculus sense - you want to return *results*.

In general, you can't return both results *and* error codes. (As I said, for pointers you can return NULL, and for functions whose domain of valid results is limited in some sense [abs()], you can, but if you're returning anything other than a pointer, int-type or floating-point-type, you're basically hosed.

Zeuthen: Writing a C library, part 1

Posted Jul 7, 2011 0:22 UTC (Thu) by cmccabe (guest, #60281) [Link]

> In general, you can't return both results *and* error codes. (As I said,
> for pointers you can return NULL, and for functions whose domain of valid
> results is limited in some sense [abs()], you can, but if you're returning
> anything other than a pointer, int-type or floating-point-type, you're
> basically hosed.
>

If we're still talking about C/C++, then you can only ever return:
* a primitive (int, float, etc.)
* a pointer
* a struct

All of those have a natural 'none of the above' value. Integer types have 0 or a negative, floats and doubles have NaN, and pointers have NULL.

If you're returning a struct by value, then you're probably using C++, since C programmers rarely return an entire structure by value. The obvious thing to do is to either return an integer error code and take a reference to the thing to be modified, or use C++ exceptions. Either way, problem solved.

Being able to return multiple values at once is nice, but it's hardly the biggest challenge when using C or C++.

Zeuthen: Writing a C library, part 1

Posted Jul 7, 2011 12:08 UTC (Thu) by jwakely (subscriber, #60262) [Link]

> In general, you can't return both results *and* error codes.
std::future<double> squerrt(double x)
{
  std::promise<double> p;
  if (x < 0)
    p.set_exception(copy_exception(std::domain_error("negative")));
  else
    p.set_value(sqrt(x));
  return p.get_future();
}

int main()
{
  double i = squerrt(-1).get();  // boom
}

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds