PARROT_ASSERT is currently defined as:

#ifdef NDEBUG
#  define PARROT_ASSERT(x) ((void)0)
#else
# define PARROT_ASSERT(x) Parrot_assert((INTVAL)(x), #x, __FILE__, __LINE__)
#endif

with

void
Parrot_assert(INTVAL condition, ARGIN(const char *condition_string),
        ARGIN(const char *file), unsigned int line)
...

PARROT_ASSERT is used to assert pointers too, for example in src/string.c:

UINTVAL
string_length(SHIM_INTERP, ARGIN(const STRING *s))
{
    PARROT_ASSERT(s);

    return s->strlen;
}

The cast from all kinds of stuff, including pointers, to INTVAL bothers me a bit. It ties pointers to INTVALs, which I guess it shouldn't.

One way to improve this (for certain values of improvement) is to change PARROT_ASSERT to:

#  define PARROT_ASSERT(x) Parrot_assert((!!(x)), #x, __FILE__, __LINE__)


Independent of this, pointer assertions should probably be explicit, to show what condition is actually asserted.

    PARROT_ASSERT(s != NULL);

Or maybe PARROT_ASSERT should have friends, like PARROT_ASSERT_PTR to assert pointers? This might do additional checks, like 0xdeadbeef or "-1" pointer. This may be a bit far fetched, though.

void
Parrot_assert_ptr(void *ptr, ARGIN(const char *condition_string),
        ARGIN(const char *file), unsigned int line)
{
    if (ptr == NULL || ptr == -1 || ptr == 0xdeadbeef)
        Parrot_confess(condition_string, file, line);
}

What do you think?

Ron

Reply via email to