mate-desktop / mate-calc

Calculator for MATE
http://www.mate-desktop.org
GNU General Public License v2.0
40 stars 33 forks source link

clear MPNumbers before return #145

Closed mbkma closed 4 years ago

rbuj commented 4 years ago

You can use labels, for instance:

void
mp_tan(const MPNumber *x, MPAngleUnit unit, MPNumber *z)
{
    MPNumber x_radians = mp_new();
    MPNumber pi = mp_new();
    MPNumber t1 = mp_new();

    convert_to_radians(x, unit, &x_radians);
    mp_get_pi(&pi);
    mp_divide_integer(&pi, 2, &t1);
    mp_subtract(&x_radians, &t1, &t1);
    mp_divide(&t1, &pi, &t1);    

    if (mp_is_integer(&t1)) {
        /* Translators: Error displayed when tangent value is undefined */
        mperr(_("Tangent is undefined for angles that are multiples of π (180°) from π∕2 (90°)"));
        mp_set_from_integer(0, z);
        goto mp_tan_cleanup;
    }

    if (mp_is_complex(x))
        mp_set_from_mp(x, z);
    else
        mp_set_from_mp(&x_radians, z);
    mpc_tan(z->num, z->num, MPC_RNDNN);

mp_tan_cleanup:
    mp_clear(&x_radians);
    mp_clear(&pi);
    mp_clear(&t1);
}
mbkma commented 4 years ago

@rbuj do you agree with this solution?

void
mp_clear_n(int arg_count, ...)
{
    MPNumber *x;
    va_list args;

    va_start(args, arg_count);
    for (int i = 0; i < arg_count ; i++)
    {
        x = va_arg(args, MPNumber*);
        mp_clear(x);
    }
    va_end(args);
}
void
mp_tan(const MPNumber *x, MPAngleUnit unit, MPNumber *z)
{
    MPNumber x_radians = mp_new();
    MPNumber pi = mp_new();
    MPNumber t1 = mp_new();

    convert_to_radians(x, unit, &x_radians);
    mp_get_pi(&pi);
    mp_divide_integer(&pi, 2, &t1);
    mp_subtract(&x_radians, &t1, &t1);
    mp_divide(&t1, &pi, &t1);    

    if (mp_is_integer(&t1)) {
        /* Translators: Error displayed when tangent value is undefined */
        mperr(_("Tangent is undefined for angles that are multiples of π (180°) from π∕2 (90°)"));
        mp_set_from_integer(0, z);
        mp_clear_n(3, &x_radians, &pi, &t1);
        return;
    }

    if (mp_is_complex(x))
        mp_set_from_mp(x, z);
    else
        mp_set_from_mp(&x_radians, z);
    mpc_tan(z->num, z->num, MPC_RNDNN);
    mp_clear_n(3, &x_radians, &pi, &t1);
}
rbuj commented 4 years ago

Do you want to use varargs for destroying all variabes in one line? Why not use varargs to create them? Please, keep the code as clear as possible and don't complicate it if you don't need to.

rbuj commented 4 years ago

Test:

$ CFLAGS="-ggdb3 -O0 -fsanitize=address" ./autogen.sh --prefix=/usr && make
$ ./src/test-mp-equation

Before (master):

SUMMARY: AddressSanitizer: 213285 byte(s) leaked in 2884 allocation(s).

After (PR+git rebase master):

SUMMARY: AddressSanitizer: 212469 byte(s) leaked in 2878 allocation(s).
mbkma commented 4 years ago

yes, you are right. Thanks for reviewing!