This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: GNU C extension: Function Error vs. Success


On 03/10/2014 03:09 PM, Shahbaz Youssefi wrote:
> Regarding C++ exceptions: exceptions are not really nice. They can
> just make your function return without you even knowing it (forgetting
> a `try/catch` or not knowing it may be needed, which is C++'s fault
> and probably could have been done better). Also, they require
> complicated operations. You can read a small complaint about it here:
> http://stackoverflow.com/a/1746368/912144 and I'm sure there are many
> others on the internet.

A few quibbles here.

Firstly, C++ exceptions do not require complicated operations: an
implementation may well do complicated things, but that's not the
same at all.  In GCC we use DWARF exception handling, which is
designed to be near-zero-cost for exceptions that are not thrown,
but is more expensive when they are.

There is no inherent reason why

    float inverse(int x)
    {
        if (x == 0)
            fail;
        return 1.0f / x;
    }

    y = inverse(x) !! goto exit_inverse_failed;

should not generate the same code as

    float inverse(int x)
    {
        if (x == 0)
            throw overflow;
        return 1.0f / x;
    }

    try {
        y = inverse(x);
    } catch (IntegerOverflow e) {
        goto exit_inverse_failed;
    }

This assumes, of course, a knowledgeable optimizing compiler.

Also, consider that C++ can already do almost what you want.
Here we have a function that returns a float wrapped with a
status:

option<float> inverse(float x) {
  if (x == 0)
    return option<float>();  // No value...
  return 1.0f / x;
}

float poo(float x) {
  option<float> res = inverse(x);
  if (res.none())
    return 0;
  return res;
}

GCC generates, quite nicely:

poo(float):
        xorps   %xmm1, %xmm1
        ucomiss %xmm1, %xmm0
        jp      .L12
        jne     .L12
        movaps  %xmm1, %xmm0
        ret
.L12:
        movss   .LC1(%rip), %xmm1
        divss   %xmm0, %xmm1
        movaps  %xmm1, %xmm0
        ret

The difference between

    y = inverse(x) !! goto exit_inverse_failed;

and

  option<float> y = inverse(x);
  if (y.none())
    goto exit_inverse_failed;

is, I suggest to you, mere syntax.  The latter is more explicit.

Andrew.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]