avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-libc-dev] What is the necessity of _FFS() ?


From: Dmitry K.
Subject: Re: [avr-libc-dev] What is the necessity of _FFS() ?
Date: Thu, 20 Oct 2005 19:11:10 +1100
User-agent: KMail/1.5

On Thursday 20 October 2005 16:01, Joerg Wunsch wrote:
> As Dmitry K. wrote:
> > What is the reason of '_FFS' appearance in the last Avr-libc CVS?
>
> ffs() is a function, and should remain a function.  It violates the
> principle of least astonishment (POLA) to suddenly have a macro by
> that name that does magic things on its arguments -- among them,
> evaluating its argument at least twice.  Think about people who'd
> innocently do something like
>
> ...
>    i = ffs(getsomevalue());
> ...
>
> or even worse:
>
>    i = ffs(rand());
>
> (where rand() clearly returns a different value for each call).

Original implementation of 'ffs' is absolutely safe.
'__buitin_constant_p' is *not* evaluate argument.
Like 'sizeof':  the function
    int foo (x)
    {
        sizeof (x++);
        return x;
    }
returns unchanged 'x'.  (I have check this with and without
optimization.)

I have check 2 functions with original ffs macro:

    int foo1 (int x)
    {
        return ffs(++x);
    }

    int foo2 (int x)
    {
        return ffs(rand(x));
    }

With optimization result is:
   foo1:
        adiw r24,1
        rcall ffs
        ret

   foo2:
        rcall rand
        rcall ffs
        ret

Without optimization:
   foo1:
        ...
   /* prologue end (size=10) */
        std Y+1,r24
        std Y+2,r25
        ldd r24,Y+1
        ldd r25,Y+2
        adiw r24,1
        std Y+1,r24
        std Y+2,r25
        rcall ffs
   /* epilogue: frame size=2 */
        ...
   foo2:
   /* prologue end (size=10) */
        std Y+1,r24
        std Y+2,r25
        ldd r24,Y+1
        ldd r25,Y+2
        rcall rand
        rcall ffs
   /* epilogue: frame size=2 */

Both funcions produce correct code with and without optimization.

[...]
> I've then asked Anatoly what's the purpose of the macro implementation
> at all, and he passed me your opinion on about having something like a
> counterpart to _BV().
I wished to emphasize only, that the 'ffs' with constant
argument is not exotic.

[...]
> (*) Historical exceptions are getc and putc, but for them, it has
> always been clearly stated they might be implemented as macros that
> evaluate their argument more than once (even though they aren't in our
> case, as our stdio does no buffering).

There are many functions, that are implemented as macroses:
sin, cos, tan, sqrt ... (This is a C99 standart, to evaluate a size
of argument: float, double or long double).
   Glibc with __GNUC__ defined: big part of standart string functions
are macroses for efficiency (__builtin_constant_p is used activly).

Thanks,
Dmitry.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]