This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: GNU C extension: Function Error vs. Success
- From: David Brown <david at westcontrol dot com>
- To: Shahbaz Youssefi <shabbyx at gmail dot com>, Andrew Haley <aph at redhat dot com>
- Cc: Julian Brown <julian at codesourcery dot com>, <gcc at gcc dot gnu dot org>
- Date: Tue, 11 Mar 2014 13:26:25 +0100
- Subject: Re: GNU C extension: Function Error vs. Success
- Authentication-results: sourceware.org; auth=none
- References: <CALeOzZ8kAOepbUsqRNWnGvHc=vAGC2M_NkHZ6+VZz3ybfs59HA at mail dot gmail dot com> <20140310145046 dot 2d5c4ca0 at octopus> <CALeOzZ8On5R7t+3_gQ+ec5Sqi4P1ysCTLUMd0ck5UK7nKiCs+A at mail dot gmail dot com> <531DF3D4 dot 9070403 at redhat dot com> <CALeOzZ_oDiKNU5SaB07ks0KHP6h=nW_9guwNobGwBAfOyL5z-Q at mail dot gmail dot com>
On 10/03/14 18:26, Shahbaz Youssefi wrote:
> I'm mostly interested in C. Nevertheless, you can of course also do
> the same in C:
>
> struct option_float
> {
> float value;
> int error_code;
> bool succeeded;
> };
>
> struct option_float inverse(int x) {
> if (x == 0)
> return (struct option_float){ .succeeded = false, .error_code = EDOM };
> return (struct option_float){ .value = 1.0f / x, .succeeded = true };
> }
>
> you get the idea. The difference is that it's hard to optimize the
> non-error execution path if the compiler is not aware of the
> semantics.
You can tell the compiler about the likely paths:
struct option_float inverse(int x) {
if (__builtin_expect(x != 0, 1)) {
return (struct option_float){ .value = 1.0f / x, .succeeded = true };
} else {
return (struct option_float){ .succeeded = false, .error_code =
EDOM };
}
> Also, with exceptions, this can happen:
>
> float inverse(int x)
> {
> if (x == 0)
> throw overflow;
> return 1.0f / x;
> }
>
> y = inverse(x);
>
> Which means control is taken from the function calling inverse without
> it explicitly allowing it, which is not in the spirit of C.
In many cases, I'd agree with you that C++ exceptions are a bit like
hidden and unexpected gotos. But in situations like this, the code is
in fact in the "spirit of C". If you try to find the inverse of 0, you
are asking for undefined behaviour - and you are getting it. You can
add extra code (checks, exceptions, etc.) to turn that undefined
behaviour into defined behaviour - but without that code it is not
unreasonable to pass the exception up the call stack or do other odd things.
>
> P.S. programming in a lot of languages is _mere syntax_ with respect
> to some others. Still, some syntaxes are good and some not. If we can
> improve GNU C's syntax to be shorter, but without loss of
> expressiveness or clarity, then why not!
>
I am not sure that it would be possible to get the sort of effect you
are looking for without disrupting the syntax too much for a gcc extension.
Speaking as an embedded developer who often wants to get the smallest
and fastest code on small processors, it would be very nice is to have
the ability to return an extra flag along with the main return value of
a function. Typically that would be a flag to indicate success or
failure, but it might have other purposes - and it could be the only
return value of an otherwise void function. Key to the implementation
would be a calling convention to use a processor condition code flag
here - that would let you generate optimal code for the "if (error)
goto" part.