lisp toy: strangest warning I've seen

Discussion in 'C Programming' started by luserXtrog, May 11, 2009.

  1. luserXtrog

    luserXtrog Guest

    Can anyone shed light upon this warning. From the line
    number it refers to the anonymous union, but I don't
    understand what the compiler's griping about.

    193(1)09:30 PM:~ 0> gcc -std=c99 -o list list.c
    list.c:12: warning: declaration does not declare anything

    #include <stdbool.h>
    #include <stdio.h>
    #include <stdlib.h>

    int error(char *s){ fprintf(stderr, "%s\n", s); exit(EXIT_FAILURE); }

    struct sexpr {
    bool atom;
    union {
    int cari;
    struct sexpr *carl;
    };
    struct sexpr *cdr;
    };

    struct list {
    int *car;
    struct list *cdr;
    };

    bool init() {
    struct list *lp, *h;
    (lp=malloc(sizeof*lp)) || error("poof!");
    h=lp;
    for(int *i = (int[]){ 42, 69, 613, 0 }; *i; i++) {
    lp->car = i;
    (lp->cdr=malloc(sizeof*lp)) || error("poof!");
    lp = lp->cdr;
    *lp = (struct list){ NULL, NULL };
    }
    return true;
    }

    struct list *read(FILE *f) {
    struct list *lp;
    int c;
    (lp=malloc(sizeof*lp)) || error("poof!");
    while( EOF!= (c=fgetc(stdin)) ) {
    switch(c) {
    case '(': lp->car = 0;
    lp->cdr = read(f);
    break;
    case ')': return NULL;
    default:
    (lp->car=malloc(sizeof*lp)) || error("poof!");
    *lp->car = c;
    }
    }
    return lp;
    }

    struct list *eval(struct list *lp) {
    return lp;
    }

    bool print(FILE *f, struct list *lp) {
    if (lp) {
    fprintf(f, "%d\n", lp->car);
    print(f,lp->cdr);
    return true;
    } else {
    return false;
    }
    }

    bool run() {
    while (print(stdout,eval(read(stdin)))) ;
    return true;
    }

    int main() {
    return init()&&run()?0:EXIT_FAILURE;
    }

    /*eof*/

    --
    lxt
     
    luserXtrog, May 11, 2009
    #1
    1. Advertising

  2. On 11 May, 03:45, luserXtrog <> wrote:
    > Can anyone shed light upon this warning. From the line
    > number it refers to the anonymous union, but I don't
    > understand what the compiler's griping about.
    >
    > 193(1)09:30 PM:~ 0> gcc -std=c99 -o list list.c
    > list.c:12: warning: declaration does not declare anything


    Standard C does not have anonymous unions. Lose the -std=c99
    part and the warning goes away.

    > #include <stdbool.h>
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > int error(char *s){ fprintf(stderr, "%s\n", s); exit(EXIT_FAILURE); }
    >
    > struct sexpr {
    > bool atom;
    > union {
    > int cari;
    > struct sexpr *carl;
    > };
    > struct sexpr *cdr;
    >
    > };


    [...]

    >
    > struct list *read(FILE *f) {
    > struct list *lp;
    > int c;
    > (lp=malloc(sizeof*lp)) || error("poof!");
    > while( EOF!= (c=fgetc(stdin)) ) {


    Do you mean fgetc(f) ?

    [...]

    --
    Who's your mama?
     
    Spiros Bousbouras, May 11, 2009
    #2
    1. Advertising

  3. luserXtrog

    luserXtrog Guest

    On May 10, 10:14 pm, Spiros Bousbouras <> wrote:
    > On 11 May, 03:45, luserXtrog <> wrote:
    >
    > > Can anyone shed light upon this warning. From the line
    > > number it refers to the anonymous union, but I don't
    > > understand what the compiler's griping about.

    >
    > > 193(1)09:30 PM:~ 0> gcc -std=c99 -o list list.c
    > > list.c:12: warning: declaration does not declare anything

    >
    > Standard C does not have anonymous unions. Lose the -std=c99
    > part and the warning goes away.
    >


    But that's even worse!
    199(1)10:19 PM:~ 0> gcc -o list list.c
    list.c: In function 'init':
    list.c:25: error: 'for' loop initial declaration used outside C99 mode

    Granted that particular loop doesn't do anything useful
    and will not be long for this earth. But I want all the goodies.

    > > #include <stdbool.h>
    > > #include <stdio.h>
    > > #include <stdlib.h>

    >
    > > int error(char *s){ fprintf(stderr, "%s\n", s); exit(EXIT_FAILURE); }

    >
    > > struct sexpr {
    > >     bool atom;
    > >     union {
    > >         int cari;
    > >         struct sexpr *carl;
    > >     };
    > >     struct sexpr *cdr;

    >
    > > };

    >
    > [...]
    >
    >
    >
    > > struct list *read(FILE *f) {
    > >     struct list *lp;
    > >     int c;
    > >     (lp=malloc(sizeof*lp)) || error("poof!");
    > >     while( EOF!= (c=fgetc(stdin)) ) {

    >
    > Do you mean fgetc(f) ?


    Um. Yes. But something else is terribly wrong with it.
    Don't anybody run this program! You have to Interrupt it
    to make it stop. And I'm trying to start over with
    the new structure (having gotten through that first John
    McCarthy paper).

    > [...]
    >
    > --
    > Who's your mama?


    trog
    as in ata-ara-ogg
    the true mouth of ogh

    --
    lxt
     
    luserXtrog, May 11, 2009
    #3
  4. On 11 May, 04:27, luserXtrog <> wrote:
    > On May 10, 10:14 pm, Spiros Bousbouras <> wrote:
    >
    > > On 11 May, 03:45, luserXtrog <> wrote:

    >
    > > > Can anyone shed light upon this warning. From the line
    > > > number it refers to the anonymous union, but I don't
    > > > understand what the compiler's griping about.

    >
    > > > 193(1)09:30 PM:~ 0> gcc -std=c99 -o list list.c
    > > > list.c:12: warning: declaration does not declare anything

    >
    > > Standard C does not have anonymous unions. Lose the -std=c99
    > > part and the warning goes away.

    >
    > But that's even worse!
    > 199(1)10:19 PM:~ 0> gcc -o list list.c
    > list.c: In function 'init':
    > list.c:25: error: 'for' loop initial declaration used outside C99 mode
    >
    > Granted that particular loop doesn't do anything useful
    > and will not be long for this earth. But I want all the goodies.


    Use a named union then. When I said "Lose the -std=c99 part" I
    wasn't making a suggestion, I was explaining what's happening.
    Personally I consider anonymous structs or unions a bug waiting
    to happen since they may lead to ambiguous field references
    which gcc may not notice.

    --
    Who's your mama?
     
    Spiros Bousbouras, May 11, 2009
    #4
  5. luserXtrog

    luserXtrog Guest

    On May 10, 10:38 pm, Spiros Bousbouras <> wrote:
    > Use a named union then. When I said "Lose the -std=c99 part" I
    > wasn't making a suggestion, I was explaining what's happening.
    > Personally I consider anonymous structs or unions a bug waiting
    > to happen since they may lead to ambiguous field references
    > which gcc may not notice.
    >


    Thank you. I consider my question answered.
    I suppose any tricks for allowing the two constructs to coexist
    are implementation-specific and therefore OT.
    Bummer.

    --
    lxt
     
    luserXtrog, May 11, 2009
    #5
  6. luserXtrog

    vivek Guest

    On May 11, 8:55 am, luserXtrog <> wrote:
    > On May 10, 10:38 pm, Spiros Bousbouras <> wrote:
    > here in struct u have defined union but no declared any union variable... try declaring it....
    > > Use a named union then. When I said "Lose the -std=c99 part" I
    > > wasn't making a suggestion, I was explaining what's happening.
    > > Personally I consider anonymous structs or unions a bug waiting
    > > to happen since they may lead to ambiguous field references
    > > which gcc may not notice.

    >
    > Thank you. I consider my question answered.
    > I suppose any tricks for allowing the two constructs to coexist
    > are implementation-specific and therefore OT.
    > Bummer.
    >
    > --
    > lxt
     
    vivek, May 11, 2009
    #6
  7. On 11 May 2009 at 2:45, luserXtrog wrote:
    > 193(1)09:30 PM:~ 0> gcc -std=c99 -o list list.c


    I'm surprised CBF hasn't been along yet to tell you that lisp is
    off-topic, without bothering to read your message and learn that the
    subject line has a typo - that's usually the way he rolls.

    Still, he's usually late to the party too, so give him 24 hours...
     
    Antoninus Twink, May 11, 2009
    #7
  8. luserXtrog <> writes:

    > On May 10, 10:38 pm, Spiros Bousbouras <> wrote:
    >> Use a named union then. When I said "Lose the -std=c99 part" I
    >> wasn't making a suggestion, I was explaining what's happening.
    >> Personally I consider anonymous structs or unions a bug waiting
    >> to happen since they may lead to ambiguous field references
    >> which gcc may not notice.

    >
    > Thank you. I consider my question answered.


    No chance! I would not recommend it for new code but to get existing
    code though a compiler that does not have anonymous unions, you will
    sometimes see:

    struct sexpr {
    bool atom;
    union {
    int cari;
    struct sexpr *carl;
    } either;
    #define cari either.cari
    #define carl either.carl
    struct sexpr *cdr;
    };

    > I suppose any tricks for allowing the two constructs to coexist
    > are implementation-specific and therefore OT.


    The above might count as such.

    --
    Ben.
     
    Ben Bacarisse, May 11, 2009
    #8
  9. luserXtrog <> writes:
    > On May 10, 10:38 pm, Spiros Bousbouras <> wrote:
    >> Use a named union then. When I said "Lose the -std=c99 part" I
    >> wasn't making a suggestion, I was explaining what's happening.
    >> Personally I consider anonymous structs or unions a bug waiting
    >> to happen since they may lead to ambiguous field references
    >> which gcc may not notice.

    >
    > Thank you. I consider my question answered.
    > I suppose any tricks for allowing the two constructs to coexist
    > are implementation-specific and therefore OT.
    > Bummer.


    Not necessarily. If you really wanted to, you could write:

    struct sexpr {
    bool atom;
    union {
    int cari;
    struct sexpr *carl;
    } foo;
    struct sexpr *cdr;
    };
    #define cari foo.cari
    #define carl foo.carl

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, May 11, 2009
    #9
  10. luserXtrog

    REH Guest

    On May 10, 10:45 pm, luserXtrog <> wrote:
    > Can anyone shed light upon this warning. From the line
    > number it refers to the anonymous union, but I don't
    > understand what the compiler's griping about.
    >


    Anonymous unions are part of C++, not C.

    REH
     
    REH, May 11, 2009
    #10
  11. In article <>,
    Keith Thompson <> wrote:

    >Not necessarily. If you really wanted to, you could write:

    [...]
    >#define cari foo.cari
    >#define carl foo.carl


    Unfortunately this pollutes the namespace, especially since it's
    common to want to use variables with the same names as fields.

    Anonymous unions make simple object-oriented programming much
    neater.

    -- Richard
    --
    Please remember to mention me / in tapes you leave behind.
     
    Richard Tobin, May 12, 2009
    #11
  12. luserXtrog

    luserXtrog Guest

    On May 11, 10:20 am, Keith Thompson <> wrote:
    > luserXtrog <> writes:
    > > On May 10, 10:38 pm, Spiros Bousbouras <> wrote:
    > >> Use a named union then. When I said "Lose the -std=c99 part" I
    > >> wasn't making a suggestion, I was explaining what's happening.
    > >> Personally I consider anonymous structs or unions a bug waiting
    > >> to happen since they may lead to ambiguous field references
    > >> which gcc may not notice.

    >
    > > Thank you. I consider my question answered.
    > > I suppose any tricks for allowing the two constructs to coexist
    > > are implementation-specific and therefore OT.
    > > Bummer.

    >
    > Not necessarily.  If you really wanted to, you could write:
    >
    > struct sexpr {
    >     bool atom;
    >     union {
    >         int cari;
    >         struct sexpr *carl;
    >     } foo;
    >     struct sexpr *cdr;};
    >
    > #define cari foo.cari
    > #define carl foo.carl
    >


    Yes. That would do it. (Props to Ben, too!)
    Apropos, I discovered that a normal declaration sans identifier
    produces quite a different warning:

    224(1)10:29 PM:~ 0> cat noid.c && make noid
    #include <stdio.h>

    int main() {
    int i;
    int;
    *((&i) + 1) = 5;
    printf("%d\n", (&i)[1]);
    return 0;
    }
    cc noid.c -o noid
    noid.c: In function 'main':
    noid.c:5: warning: useless type name in empty declaration

    Oddly enough, on my system this prints 5 just before
    segfaulting.

    So it's possible that space for the union with no name
    is included in the struct although the internal names aren't
    accessable.

    But I've decided against it all.
    Since you're all here, I present take 2.
    No real questions at the moment but if anything jumps out
    as misguided, I'd appreciate a heads-up.

    #include <stdbool.h>
    #include <stdio.h>
    #include <stdlib.h>

    int error(char *s){ fprintf(stderr, "%s\n", s); exit(EXIT_FAILURE); }

    union word {
    int i;
    struct sexpr *link;
    };

    struct sexpr {
    bool atom; //if true, cdr s.b. NULL
    union word car;
    struct sexpr *cdr;
    };

    struct sexpr *globl;

    bool init() {
    struct sexpr *lp, *h;
    (lp=malloc(sizeof*lp)) || error("poof!");
    h=lp;
    for(int *i = (int[]){ 42, 69, 613, 0 }; *i; i++) {
    lp->atom = 0;
    (lp->car.link=malloc(sizeof*lp->car.link)) || error("poof!");
    lp->car.link->atom = 1;
    lp->car.link->car.i = *i;
    lp->car.link->cdr = NULL;
    (lp->cdr=malloc(sizeof*lp)) || error("poof!");
    lp = lp->cdr;
    }
    free(lp);
    lp=NULL;
    globl=h;
    return true;
    }

    bool print(FILE *f, struct sexpr *lp) {
    if (lp) {
    if (lp->atom) {
    fprintf(f, "%d\n", lp->car.i);
    } else {
    if (lp->car.link) print(f,lp->car.link);
    if (lp->cdr) print(f,lp->cdr);
    }
    return true;
    } else {
    return false;
    }
    }

    bool run() {
    //while (print(stdout,eval(read(stdin)))) ;
    print(stdout,globl);
    return true;
    }

    int main() {
    return init()&&run()?0:EXIT_FAILURE;
    }

    /*eof*/
     
    luserXtrog, May 12, 2009
    #12
  13. luserXtrog <> writes:

    <snip>
    > Apropos, I discovered that a normal declaration sans identifier
    > produces quite a different warning:
    >
    > 224(1)10:29 PM:~ 0> cat noid.c && make noid
    > #include <stdio.h>
    >
    > int main() {
    > int i;
    > int;
    > *((&i) + 1) = 5;
    > printf("%d\n", (&i)[1]);
    > return 0;
    > }
    > cc noid.c -o noid
    > noid.c: In function 'main':
    > noid.c:5: warning: useless type name in empty declaration
    >
    > Oddly enough, on my system this prints 5 just before
    > segfaulting.


    I don't see the oddity (a messed up stack often shows up only on
    return).

    > So it's possible that space for the union with no name
    > is included in the struct although the internal names aren't
    > accessable.
    >
    > But I've decided against it all.
    > Since you're all here, I present take 2.
    > No real questions at the moment but if anything jumps out
    > as misguided, I'd appreciate a heads-up.
    >
    > #include <stdbool.h>
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > int error(char *s){ fprintf(stderr, "%s\n", s); exit(EXIT_FAILURE); }
    >
    > union word {
    > int i;
    > struct sexpr *link;
    > };
    >
    > struct sexpr {
    > bool atom; //if true, cdr s.b. NULL
    > union word car;
    > struct sexpr *cdr;
    > };


    I don't like the asymmetry. I you want an atom to use only one
    pointer's worth of space (as is often done -- the cdr pointer being
    used for the property list) I'd go so far as to do this:

    union word {
    int i;
    struct sexpr *link;
    };

    struct sexpr {
    bool atom;
    union word car;
    struct { struct sexpr *link; } cdr;
    };

    so that the pointers are sp->cdr.link and sp->car.link.

    If you want to get the most storage out of an atom, I'd make is span
    both links although there is no portable way to define an int that is
    the size of two pointers:

    struct sexp {
    bool atom;
    union {
    long long int i;
    struct {
    struct sexp *car, *cdr;
    } pair;
    } sexp;
    };

    though this gives the rather messy names sp->sexp.pair.car and
    sp->sexp.pair.cdr.

    I'll just throw in the option that, for a fixed size heap, declaring
    each part separately has some merit. Gregory Chaitin's tiny LISP
    interpreter uses:

    long car[SIZE], cdr[SIZE]; /* tree storage */
    short atom[SIZE]; /* is it an atom? */
    short numb[SIZE]; /* is it a number? */

    and so on. (He uses indexes rather than pointers but you get the idea).

    --
    Ben.
     
    Ben Bacarisse, May 12, 2009
    #13
  14. luserXtrog

    luserXtrog Guest

    On May 12, 9:47 am, Ben Bacarisse <> wrote:
    > luserXtrog <> writes:

    <snippity>
    > > Since you're all here, I present take 2.
    > > No real questions at the moment but if anything jumps out
    > > as misguided, I'd appreciate a heads-up.

    >

    <snipped #includes>
    >
    > > union word {
    > >     int i;
    > >     struct sexpr *link;
    > > };

    >
    > > struct sexpr {
    > >     bool atom; //if true, cdr s.b. NULL
    > >     union word car;
    > >     struct sexpr *cdr;
    > > };

    >
    > I don't like the asymmetry.  I you want an atom to use only one
    > pointer's worth of space (as is often done -- the cdr pointer being
    > used for the property list)


    Ah. I'd forgotten about the property list (or association list,
    as the original paper designates them).

    > I'd go so far as to do this:
    >
    >   union word {
    >       int i;
    >       struct sexpr *link;
    >   };
    >
    >   struct sexpr {
    >       bool atom;
    >       union word car;
    >       struct { struct sexpr *link; } cdr;
    >   };
    >
    > so that the pointers are sp->cdr.link and sp->car.link.


    Yes. Thanks. That's much better.

    > If you want to get the most storage out of an atom, I'd make is span
    > both links although there is no portable way to define an int that is
    > the size of two pointers:
    >
    >   struct sexp {
    >       bool atom;
    >       union {
    >           long long int i;
    >           struct {
    >               struct sexp *car, *cdr;
    >           } pair;
    >       } sexp;
    >   };
    >
    > though this gives the rather messy names sp->sexp.pair.car and
    > sp->sexp.pair.cdr.
    >
    > I'll just throw in the option that, for a fixed size heap, declaring
    > each part separately has some merit.  Gregory Chaitin's tiny LISP
    > interpreter uses:
    >
    >  long car[SIZE], cdr[SIZE]; /* tree storage */
    >  short atom[SIZE]; /* is it an atom? */
    >  short numb[SIZE]; /* is it a number? */
    >
    > and so on.  (He uses indexes rather than pointers but you get the idea)..
    >


    Interesting. For the moment I prefer the structs so related data
    is kept together. But garbage collection would be much simpler
    with fixed-size arrays.

    Thanks again.
    --
    lxt
     
    luserXtrog, May 13, 2009
    #14
  15. luserXtrog

    Alan Curry Guest

    In article <>,
    luserXtrog <> wrote:
    >
    >Granted that particular loop doesn't do anything useful
    >and will not be long for this earth. But I want all the goodies.


    -std=c99 isn't that. But if you look at the documentation, in the list of
    recognized -std= parameters you should find one that does mean effectively
    "all the goodies".

    --
    Alan Curry
     
    Alan Curry, May 13, 2009
    #15
  16. luserXtrog

    Richard Bos Guest

    luserXtrog <> wrote:

    > (lp=malloc(sizeof*lp)) || error("poof!");


    Not answering your question here, but... C is not PERL. Blech-an'a-half.

    Richard
     
    Richard Bos, May 13, 2009
    #16
  17. luserXtrog

    luserXtrog Guest

    On May 13, 10:11 am, (Richard Bos) wrote:
    > luserXtrog <> wrote:
    > >     (lp=malloc(sizeof*lp)) || error("poof!");

    >
    > Not answering your question here, but... C is not PERL. Blech-an'a-half.
    >


    I knew somebody would have strong feelings against this form
    if I continued to use it; but I think it reads better than
    a negative predicate. It's also shorter than the alternative:

    if ((lp=malloc(sizeof*lp)) == NULL) error("poof!");

    For full disclosure, it does require extra decoration to pass splint:

    (void)((lp=malloc(sizeof*lp)) || error("poof!"));

    But it's still shorter.

    --
    lxt
     
    luserXtrog, May 13, 2009
    #17
  18. luserXtrog

    jameskuyper Guest

    Richard Bos wrote:
    > luserXtrog <> wrote:
    >
    > > (lp=malloc(sizeof*lp)) || error("poof!");

    >
    > Not answering your question here, but... C is not PERL. Blech-an'a-half.


    Nonetheless, the perl features that this idiom relies upon were all
    borrowed from C, and it works just as well in C as in perl. I think
    it's a somewhat confusing idiom, but that's just a true in perl as in
    C.
     
    jameskuyper, May 13, 2009
    #18
  19. On 13 May, 17:20, jameskuyper <> wrote:
    > Richard Bos wrote:
    > > luserXtrog <> wrote:

    >
    > > > (lp=malloc(sizeof*lp)) || error("poof!");

    >
    > > Not answering your question here, but... C is not PERL. Blech-an'a-half.

    >
    > Nonetheless, the perl features that this idiom relies upon were all
    > borrowed from C, and it works just as well in C as in perl.


    Perhaps Perl borrowed them from Unix shells rather than C?

    --
    Let's bring people who google for "Paris Hilton" to
    C programming.
     
    Spiros Bousbouras, May 13, 2009
    #19
  20. luserXtrog <> writes:
    > On May 13, 10:11 am, (Richard Bos) wrote:
    >> luserXtrog <> wrote:
    >> >     (lp=malloc(sizeof*lp)) || error("poof!");

    >>
    >> Not answering your question here, but... C is not PERL. Blech-an'a-half.
    >>

    >
    > I knew somebody would have strong feelings against this form
    > if I continued to use it; but I think it reads better than
    > a negative predicate. It's also shorter than the alternative:
    >
    > if ((lp=malloc(sizeof*lp)) == NULL) error("poof!");
    >
    > For full disclosure, it does require extra decoration to pass splint:
    >
    > (void)((lp=malloc(sizeof*lp)) || error("poof!"));
    >
    > But it's still shorter.


    Yes, it's shorter. You can make it shorter still by deleting the
    spaces around the "||" operator.

    Are you assuming that making it shorter is a *good* thing?

    Within limits, it can be; it's certainly possible to be too verbose.
    <OT>And I certainly use the "do-something or die" idiom in Perl.</OT>

    But here's how I'd write it:

    if ((lp = malloc(sizeof *lp) == NULL) {
    error("poof!");
    }

    or even:

    lp = malloc(sizeof *lp);
    if (lp == NULL) {
    error("poof!");
    }

    Note, among other things, the spaces around the "=" operator and after
    the "sizeof" operator.

    Y M M V.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, May 13, 2009
    #20
    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. Emilio

    Strangest Control behaviour ?!

    Emilio, Oct 15, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    325
    Emilio
    Oct 15, 2003
  2. Neo Geshel
    Replies:
    7
    Views:
    507
    Neo Geshel
    Jul 1, 2005
  3. Jannick

    The strangest problem....

    Jannick, Oct 9, 2003, in forum: C Programming
    Replies:
    27
    Views:
    762
    Dan Pop
    Oct 17, 2003
  4. bolega
    Replies:
    5
    Views:
    2,480
    nanothermite911fbibustards
    Jun 13, 2010
  5. bolega
    Replies:
    5
    Views:
    347
    nanothermite911fbibustards
    Jun 13, 2010
Loading...

Share This Page