functions with no side-effects

Discussion in 'C Programming' started by Rouben Rostamian, Oct 12, 2003.

  1. Consider the following illustrative program:

    #include <stdio.h>

    double f(double x)
    {
    return x*x;
    }

    double g(double x)
    {
    puts("hello world");
    return x*x;
    }

    int main(void)
    {
    double s = 0.0;
    int i;

    for (i=0; i<10000; i++)
    s += f(2.0); /* f(2.0) is always 4.0 */

    for (i=0; i<10000; i++)
    s += g(2.0); /* g(2.0) is always 4.0 */

    printf("s = %g\n", s);
    return 0;
    }

    Does standard C provide a mechanism whereby one can reassure the
    compiler that the function f() produces no side-effects while the
    function g() has side-effects?

    If such a mechanism existed, then an optimizing compiler might replace
    f(2.0) by 4.0 to avoid 10000 function calls, but it wouldn't replace
    g(2.0) by 4.0.

    Something in the back of my mind tells me that such a mechanism exists
    but I may be (a) just imagining it; (b) thinking of a non-standard
    compiler; or (c) a language other than C.

    I would appreciate it if someone would set me straight.

    --
    Rouben Rostamian <>
     
    Rouben Rostamian, Oct 12, 2003
    #1
    1. Advertising

  2. Rouben Rostamian

    Ben Pfaff Guest

    (Rouben Rostamian) writes:

    > Does standard C provide a mechanism whereby one can reassure the
    > compiler that the function f() produces no side-effects while the
    > function g() has side-effects?


    No. There is a GNU C extension for that, but it's non-standard.

    The `inline' keyword in C99 may help, however.

    > If such a mechanism existed, then an optimizing compiler might replace
    > f(2.0) by 4.0 to avoid 10000 function calls, but it wouldn't replace
    > g(2.0) by 4.0.


    In the code you presented, the compiler can easily tell that f()
    has no side effects, because it has already seen f() when it
    compiles the call to it.
    --
    int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    );}return 0;}
     
    Ben Pfaff, Oct 12, 2003
    #2
    1. Advertising

  3. Rouben Rostamian wrote:
    > Does standard C provide a mechanism whereby one can reassure the
    > compiler that the function f() produces no side-effects while the
    > function g() has side-effects?


    There's isn't a standard mechanism for doing this, although some
    compilers have extensions. GCC, for example, supports so-called
    "function attributes" which allow you to supply this information to
    the compiler:

    http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Function-Attributes.html#Function Attributes

    (see "const" and "pure" in particular). In trivial cases, such as the
    ones in your example, an optimizing compiler should be able to work
    such things out by itself, but it's not always possible:

    int every(int predicate(const void *),
    const void *const*vals,
    size_t nvals)
    {
    for (size_t i = 0; i < nvals; i++) {
    if (!predicate(vals)) {
    return 0;
    }
    }
    return 1;
    }

    "every" itself doesn't have any side effects, but the function called
    through "predicate" might; it can't be determined at compile-time in
    general. If you have some way of telling the compiler that
    "predicate" has no side effects then it could, in theory, do all sorts
    of interesting optimizations, including memoizing both the "predicate"
    and "every" functions, avoiding the overhead of calling them multiple
    times with the same arguments. I doubt that any C compilers actually
    do that sort of thing (unless the argument values are known at
    compile-time), but it's by no means unknown in functional languages
    (where side-effect free functions are more common).

    Jeremy.
     
    Jeremy Yallop, Oct 12, 2003
    #3
  4. Rouben Rostamian

    cody Guest

    "Jeremy Yallop" <> schrieb im Newsbeitrag
    news:bmcgab$k7im1$-berlin.de...
    >

    http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Function-Attributes.html#Functio
    n%20Attributes
    >
    > (see "const" and "pure" in particular). In trivial cases, such as the
    > ones in your example, an optimizing compiler should be able to work
    > such things out by itself, but it's not always possible:
    >
    > int every(int predicate(const void *),
    > const void *const*vals,
    > size_t nvals)
    > {
    > for (size_t i = 0; i < nvals; i++) {
    > if (!predicate(vals)) {
    > return 0;
    > }
    > }
    > return 1;
    > }
    >
    > "every" itself doesn't have any side effects, but the function called
    > through "predicate" might; it can't be determined at compile-time in
    > general. If you have some way of telling the compiler that
    > "predicate" has no side effects then it could, in theory, do all sorts
    > of interesting optimizations, including memoizing both the "predicate"
    > and "every" functions, avoiding the overhead of calling them multiple
    > times with the same arguments. I doubt that any C compilers actually
    > do that sort of thing (unless the argument values are known at
    > compile-time), but it's by no means unknown in functional languages
    > (where side-effect free functions are more common).



    That should be no problem. If one could apply such attributes to function
    pointer too,
    then the compiler would know wheather side effects are possible or not:

    int every(int predicate(pure const void *), /* note "pure" in the
    declaration of the function pointer */
    const void *const*vals,
    size_t nvals)
    {
    for (size_t i = 0; i < nvals; i++) {
    if (!predicate(vals)) {
    return 0;
    }
    }
    return 1;
    }

    if the function pointer is declared without pure one can pass every function
    he likes, and the compiler must assume that
    every() has side effects. But if you declare the function pointer as pure
    one can only pass pure functions to every() and the compiler
    can assume that every() doesn't have any side effects.

    i don't know wheather or not that is the case, if not consider this as a
    proposal for future compilers.

    --
    cody

    [Freeware, Games and Humor]
    www.deutronium.de.vu || www.deutronium.tk
     
    cody, Oct 12, 2003
    #4
  5. Rouben Rostamian

    Dan Pop Guest

    In <> Ben Pfaff <> writes:

    > (Rouben Rostamian) writes:
    >
    >> Does standard C provide a mechanism whereby one can reassure the
    >> compiler that the function f() produces no side-effects while the
    >> function g() has side-effects?

    >
    >No. There is a GNU C extension for that, but it's non-standard.
    >
    >The `inline' keyword in C99 may help, however.


    How? What is preventing a C99 inline function from calling printf?

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Oct 13, 2003
    #5
  6. Rouben Rostamian

    CBFalconer Guest

    Dan Pop wrote:
    > Ben Pfaff <> writes:
    > > (Rouben Rostamian) writes:
    > >
    > >> Does standard C provide a mechanism whereby one can reassure
    > >> the compiler that the function f() produces no side-effects
    > >> while the function g() has side-effects?

    > >
    > > No. There is a GNU C extension for that, but it's non-standard.
    > >
    > > The `inline' keyword in C99 may help, however.

    >
    > How? What is preventing a C99 inline function from calling printf?


    I think you misconstrued Bens comments. If the function is
    'inline' the compiler is generating its code within the piece that
    calls it, so it can look at the generated sequence and see that
    there are no side effects, without any help.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Oct 13, 2003
    #6
  7. Rouben Rostamian

    Dan Pop Guest

    In <> CBFalconer <> writes:

    >Dan Pop wrote:
    >> Ben Pfaff <> writes:
    >> > (Rouben Rostamian) writes:
    >> >
    >> >> Does standard C provide a mechanism whereby one can reassure
    >> >> the compiler that the function f() produces no side-effects
    >> >> while the function g() has side-effects?
    >> >
    >> > No. There is a GNU C extension for that, but it's non-standard.
    >> >
    >> > The `inline' keyword in C99 may help, however.

    >>
    >> How? What is preventing a C99 inline function from calling printf?

    >
    >I think you misconstrued Bens comments. If the function is
    >'inline' the compiler is generating its code within the piece that
    >calls it, so it can look at the generated sequence and see that
    >there are no side effects, without any help.


    It is not inline that magically does that, but the fact that the function
    definition is visible to the compiler. You don't need inline in order to
    make the function definition visible to the compiler.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Oct 14, 2003
    #7
  8. Rouben Rostamian

    CBFalconer Guest

    Dan Pop wrote:
    >
    > In <> CBFalconer <> writes:
    >
    > >Dan Pop wrote:
    > >> Ben Pfaff <> writes:
    > >> > (Rouben Rostamian) writes:
    > >> >
    > >> >> Does standard C provide a mechanism whereby one can reassure
    > >> >> the compiler that the function f() produces no side-effects
    > >> >> while the function g() has side-effects?
    > >> >
    > >> > No. There is a GNU C extension for that, but it's non-standard.
    > >> >
    > >> > The `inline' keyword in C99 may help, however.
    > >>
    > >> How? What is preventing a C99 inline function from calling printf?

    > >
    > >I think you misconstrued Bens comments. If the function is
    > >'inline' the compiler is generating its code within the piece that
    > >calls it, so it can look at the generated sequence and see that
    > >there are no side effects, without any help.

    >
    > It is not inline that magically does that, but the fact that the function
    > definition is visible to the compiler. You don't need inline in order to
    > make the function definition visible to the compiler.


    In theory, yes. However, do you know of any compilers that go to
    the trouble of characterizing each function in that manner? I
    suspect they all limit their knowledge to whatever is carried in
    the prototype.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Oct 14, 2003
    #8
  9. Rouben Rostamian

    Kevin Bracey Guest

    In message <>
    CBFalconer <> wrote:

    > Dan Pop wrote:
    > >
    > > It is not inline that magically does that, but the fact that the function
    > > definition is visible to the compiler. You don't need inline in order to
    > > make the function definition visible to the compiler.

    >
    > In theory, yes. However, do you know of any compilers that go to
    > the trouble of characterizing each function in that manner? I
    > suspect they all limit their knowledge to whatever is carried in
    > the prototype.


    I've not seen one. However, the majority of "pure" functions in practice are
    likely to be ones small enough for a real-world compiler to consider
    auto-inlining, which would achieve a similar effect.

    --
    Kevin Bracey, Principal Software Engineer
    Tematic Ltd Tel: +44 (0) 1223 503464
    182-190 Newmarket Road Fax: +44 (0) 1223 503458
    Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
     
    Kevin Bracey, Oct 14, 2003
    #9
  10. Rouben Rostamian

    Dan Pop Guest

    In <> CBFalconer <> writes:

    >Dan Pop wrote:
    >>
    >> In <> CBFalconer <> writes:
    >>
    >> >Dan Pop wrote:
    >> >> Ben Pfaff <> writes:
    >> >> > (Rouben Rostamian) writes:
    >> >> >
    >> >> >> Does standard C provide a mechanism whereby one can reassure
    >> >> >> the compiler that the function f() produces no side-effects
    >> >> >> while the function g() has side-effects?
    >> >> >
    >> >> > No. There is a GNU C extension for that, but it's non-standard.
    >> >> >
    >> >> > The `inline' keyword in C99 may help, however.
    >> >>
    >> >> How? What is preventing a C99 inline function from calling printf?
    >> >
    >> >I think you misconstrued Bens comments. If the function is
    >> >'inline' the compiler is generating its code within the piece that
    >> >calls it, so it can look at the generated sequence and see that
    >> >there are no side effects, without any help.

    >>
    >> It is not inline that magically does that, but the fact that the function
    >> definition is visible to the compiler. You don't need inline in order to
    >> make the function definition visible to the compiler.

    >
    >In theory, yes. However, do you know of any compilers that go to
    >the trouble of characterizing each function in that manner? I
    >suspect they all limit their knowledge to whatever is carried in
    >the prototype.


    They don't have to do it for inline functions, either. Why should a
    compiler care whether an inline function has side effects or not? The
    reasons, whatever they are, apply to both kinds of functions.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Oct 15, 2003
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jim Bancroft
    Replies:
    2
    Views:
    2,418
    =?Utf-8?B?UmFodWwgQW5hbmQ=?=
    Dec 28, 2004
  2. Anonieko
    Replies:
    0
    Views:
    1,950
    Anonieko
    Aug 12, 2005
  3. VisionSet
    Replies:
    7
    Views:
    474
    Michael Rauscher
    Nov 9, 2004
  4. Jason Heyes
    Replies:
    10
    Views:
    545
    red floyd
    Dec 21, 2004
  5. Giuseppe

    Re: Newbie-Side effects?

    Giuseppe, Jun 24, 2003, in forum: C Programming
    Replies:
    0
    Views:
    1,167
    Giuseppe
    Jun 24, 2003
Loading...

Share This Page