Variable declaration syntax

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Adam Warner

    Variable declaration syntax

    Hi all,

    Just before Christmas Chris Torek gave me some great advice about closures in C:
    <http://groups.google.c o.nz/groups?selm=cqc l3k030vj%40news 3.newsguy.com&o utput=gplain>

    It includes this declaration of a function pointer variable called fp:
    void (*fp)(void *);

    What does the syntax above mean? I can only digest it as void * fp,
    i.e. fp is a pointer to void.

    Thanks,
    Adam
  • Michael Mair

    #2
    Re: Variable declaration syntax

    > Just before Christmas Chris Torek gave me some great advice about closures in C:[color=blue]
    > <http://groups.google.c o.nz/groups?selm=cqc l3k030vj%40news 3.newsguy.com&o utput=gplain>
    >
    > It includes this declaration of a function pointer variable called fp:
    > void (*fp)(void *);
    >
    > What does the syntax above mean? I can only digest it as void * fp,
    > i.e. fp is a pointer to void.[/color]

    fp is a pointer to a function returning void with a parameter list
    consisting of a void *.

    example:

    void do_naught (void *);
    void do_aught (void *);

    .....

    if (bla)
    fp = do_aught;
    else
    fp = do_naught;

    .....

    /* Call the appropriate function through fp */
    (*fp)(address);

    .....

    (*fp)(another_o ne);

    .....

    Advantage: You have not to ask for "bla" all the time but set
    fp to the function you need.

    If you have problems with C declarations such as
    int (*p)[10];
    vs
    int *p[10];
    you could search for the program cdecl which does nothing but
    translate gibberish<->english where gibberish are C declarations.


    Cheers
    Michael
    --
    E-Mail: Mine is a gmx dot de address.

    Comment

    • Mike Wahler

      #3
      Re: Variable declaration syntax


      "Adam Warner" <usenet@consult ing.net.nz> wrote in message
      news:pan.2005.0 1.02.12.00.47.2 211@consulting. net.nz...[color=blue]
      > Hi all,
      >
      > Just before Christmas Chris Torek gave me some great advice about closures[/color]
      in C:[color=blue]
      >[/color]
      <http://groups.google.co.nz/groups?se...wsguy.com&outp
      ut=gplain>[color=blue]
      >
      > It includes this declaration of a function pointer variable called fp:
      > void (*fp)(void *);
      >
      > What does the syntax above mean? I can only digest it as void * fp,
      > i.e. fp is a pointer to void.[/color]

      'fp' is a pointer to a function which takes a single argument of type
      'void *', and does not return a value. Search the web for a utility
      called 'cdecl', which can take a declaration and tell you what
      it means.


      -Mike


      Comment

      • Adam Warner

        #4
        Re: Variable declaration syntax

        Hi Michael Mair,
        On Sun, 02 Jan 2005 13:10:56 +0100, Michael Mair wrote:[color=blue][color=green]
        >> Just before Christmas Chris Torek gave me some great advice about closures in C:
        >> <http://groups.google.c o.nz/groups?selm=cqc l3k030vj%40news 3.newsguy.com&o utput=gplain>
        >>
        >> It includes this declaration of a function pointer variable called fp:
        >> void (*fp)(void *);[/color]
        >
        > fp is a pointer to a function returning void with a parameter list
        > consisting of a void *.[/color]

        Thanks, I've finally grokked the syntax! As demonstrated below:

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

        unsigned int uinc1 (int x) { return ++x; }

        unsigned int uinc2 (int x) { return x+=2; }

        int main() {
        //seed random number generator, portably
        struct tm epoch;
        epoch.tm_year=2 7; epoch.tm_mon=9-1; epoch.tm_mday=4 ; epoch.tm_isdst=-1;
        epoch.tm_hour=0 ; epoch.tm_min=0; epoch.tm_sec=0;
        clock_t current_clock=c lock();
        time_t current_time=ti me(&current_clo ck);
        time_t time_since_epoc h=mktime(&epoch );
        double diff=difftime(c urrent_time, time_since_epoc h);
        unsigned int seed=(unsigned int) diff;
        printf("Seed is %u\n", seed);
        srand(seed);

        unsigned int (* fp) (int);
        //Note: The pseudo random number generator may be poor
        if (rand()%2==0) fp=uinc1; else fp=uinc2;
        unsigned int sum=fp(1);
        printf("Sum is %u\n", sum);

        return 0;
        }

        BTW I found cdecl was packaged for Debian.

        Regards,
        Adam

        Comment

        • john_bode@my-deja.com

          #5
          Re: Variable declaration syntax


          Adam Warner wrote:[color=blue]
          > Hi all,
          >
          > Just before Christmas Chris Torek gave me some great advice about[/color]
          closures in C:[color=blue]
          >[/color]
          <http://groups.google.c o.nz/groups?selm=cqc l3k030vj%40news 3.newsguy.com&o utput=gplain>[color=blue]
          >
          > It includes this declaration of a function pointer variable called[/color]
          fp:[color=blue]
          > void (*fp)(void *);
          >
          > What does the syntax above mean? I can only digest it as void * fp,
          > i.e. fp is a pointer to void.
          >[/color]

          Here's how I break things like this down:

          fp -- fp
          *fp -- is a pointer
          (*fp)() -- to a function
          (*fp)(void *) -- taking a void * parameter
          void (*fp)(void *) -- and returning void

          C follows a "declaratio n mimics use" paradigm; namely, the declaration
          of an object should look as much as possible like how it's actually
          referenced in the code. For example, if you have a 10-element array of
          int, you'd access the i'th element as a[i]. So, the declaration should
          look like this:

          int a[10];

          The type of a is "10-element array of int". However, the type
          specifier "int" says nothing about the "array-ness" of a. To convey
          this additional information, C uses "declarator s". In the declaration
          above, a[10] is the declarator, and a is the actual variable being
          declared.

          Similarly for pointers:

          int *a;

          a is a pointer to int; the "pointer-ness" is specified in the
          declarator *a. Note that this is why

          int* a, b;

          doesn't work the way people expect -- the * indirection operator is
          associated with the identifer a, *not* the type specifier int. This
          also applies in typedefs:

          typedef int (*foo)(int x, double y);

          This declares foo as a synonym for the type "pointer to function taking
          one int and one double parameter and returning int".


          Operator precedence matters in declarators. There is a huge difference
          between

          int *a[10]; // 10-element array of pointers to int

          and

          int (*a)[10]; // Pointer to 10-element array of int

          Similarly with function declarators:

          int *f(void); // f is a function taking no parameters returning int *

          vs.

          int (*f){void); // f is a pointer to a function taking no parameters
          and returning int

          If you wanna get totally nuts:

          f -- f
          *f -- is a pointer
          (*f)[10] -- to a 10-element array
          *(*f)[10] -- of pointers
          (*(*f)[10])() -- to functions
          (*(*f)[10])(int x) -- taking a single int parameter
          *(*(*f)[10])(int x) -- returning pointers
          double *(*(*f)[10])(int x) -- to double.

          And it would be called as

          double *dp = (*(*f)[i])(n);

          Actually, C allows you to elide the dereference operator when calling a
          function through a pointer, so the call looks like a normal function
          call (i.e., given a function pointer f, you can write either (*f)(n) or
          f(n) when you call it). But that means the above call could be written
          as

          double db = (*f)[i](n);

          which I think just looks ugly.

          So when you're confronted with a hairy declaration, just follow these
          steps:

          0. Separate the declarator from the type specifier and qualifiers;
          1. Find the identifier in the declarator;
          2. Work from the identifier out, observing rules of operator
          precedence (subscript [] and function call () operators are evaluated
          before the indirection * operator, unless expliticly grouped by
          parens);
          3. Apply type specifier and qualifiers.

          If you don't have one, get a copy of the C language grammar (a good C
          reference will have it as an appendix; I use Harbison & Steele's "C: A
          Reference Manual", 5th ed.) and trace through declarator syntax.
          Things will suddenly make a lot more sense.

          Comment

          • Chris McDonald

            #6
            Re: Variable declaration syntax

            >Adam Warner wrote:[color=blue][color=green]
            >> Hi all,
            >>
            >> Just before Christmas Chris Torek gave me some great advice about[/color]
            >closures in C:[color=green]
            >>[/color]
            ><http://groups.google.c o.nz/groups?selm=cqc l3k030vj%40news 3.newsguy.com&o utput=gplain>[color=green]
            >>
            >> It includes this declaration of a function pointer variable called[/color]
            >fp:[color=green]
            >> void (*fp)(void *);
            >>
            >> What does the syntax above mean? I can only digest it as void * fp,
            >> i.e. fp is a pointer to void.[/color][/color]


            If your system has the utility 'cdecl', you may find that to be of some
            assistance, too.

            _______________ _______________ _______________ _______________ _______________ ___
            Dr Chris McDonald E: chris@csse.uwa. edu.au
            Computer Science & Software Engineering W: http://www.csse.uwa.edu.au/~chris
            The University of Western Australia, M002 T: +618 6488 2533
            Crawley, Western Australia, 6009 F: +618 6488 1089

            Comment

            • Mark McIntyre

              #7
              Re: Variable declaration syntax

              On Mon, 3 Jan 2005 18:10:42 +0000 (UTC), in comp.lang.c , Chris McDonald
              <chris@csse.uwa .edu.au> wrote:
              [color=blue]
              >
              >If your system has the utility 'cdecl', you may find that to be of some
              >assistance, too.[/color]

              and if it doesn't , you can get it from the internet

              --
              Mark McIntyre
              CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
              CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt >

              ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
              http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
              ----= East and West-Coast Server Farms - Total Privacy via Encryption =----

              Comment

              • Adam Warner

                #8
                Re: Variable declaration syntax

                Hi john_bode,
                On Mon, 03 Jan 2005 08:32:09 -0800, john_bode wrote:[color=blue]
                > C follows a "declaratio n mimics use" paradigm; namely, the declaration
                > of an object should look as much as possible like how it's actually
                > referenced in the code. For example, if you have a 10-element array of
                > int, you'd access the i'th element as a[i]. So, the declaration should
                > look like this:
                >
                > int a[10];
                >
                > The type of a is "10-element array of int". However, the type
                > specifier "int" says nothing about the "array-ness" of a. To convey
                > this additional information, C uses "declarator s". In the declaration
                > above, a[10] is the declarator, and a is the actual variable being
                > declared.
                >
                > Similarly for pointers:
                >
                > int *a;
                >
                > a is a pointer to int; the "pointer-ness" is specified in the
                > declarator *a. Note that this is why
                >
                > int* a, b;
                >
                > doesn't work the way people expect -- the * indirection operator is
                > associated with the identifer a, *not* the type specifier int.[/color]

                Thanks! I've printed out your post for later reference.

                This part of C's declaration syntax borders upon insanity. I don't care
                what *a is, I want to know the type of a itself! I only grokked what was
                going on when I started writing "int *a" as "int * a", i.e. a itself is a
                pointer to int. And now I know why no one writes that--because it breaks
                down with the additional "declaratio n mimics use" paradigm.

                Anybody would think the compiler's supposed to be omnipotent. How the heck
                does "**a" mimic use if the majority of the time I'm only following the
                first pointer, or passing a itself? It's an extra layer in the declaration
                syntax that shouldn't be there!

                Understand this explains a _lot_. I know why I've got to start writing
                "int *a" instead of "int* a" or "int * a". In a saner world one would
                actually declare the type of a variable instead of also having to second
                guess how it should look when used.

                Have fun,
                Adam

                Comment

                • john_bode@my-deja.com

                  #9
                  Re: Variable declaration syntax


                  Adam Warner wrote:[color=blue]
                  > Hi john_bode,
                  > On Mon, 03 Jan 2005 08:32:09 -0800, john_bode wrote:[color=green]
                  > > C follows a "declaratio n mimics use" paradigm; namely, the[/color][/color]
                  declaration[color=blue][color=green]
                  > > of an object should look as much as possible like how it's actually
                  > > referenced in the code. For example, if you have a 10-element[/color][/color]
                  array of[color=blue][color=green]
                  > > int, you'd access the i'th element as a[i]. So, the declaration[/color][/color]
                  should[color=blue][color=green]
                  > > look like this:
                  > >
                  > > int a[10];
                  > >
                  > > The type of a is "10-element array of int". However, the type
                  > > specifier "int" says nothing about the "array-ness" of a. To[/color][/color]
                  convey[color=blue][color=green]
                  > > this additional information, C uses "declarator s". In the[/color][/color]
                  declaration[color=blue][color=green]
                  > > above, a[10] is the declarator, and a is the actual variable being
                  > > declared.
                  > >
                  > > Similarly for pointers:
                  > >
                  > > int *a;
                  > >
                  > > a is a pointer to int; the "pointer-ness" is specified in the
                  > > declarator *a. Note that this is why
                  > >
                  > > int* a, b;
                  > >
                  > > doesn't work the way people expect -- the * indirection operator is
                  > > associated with the identifer a, *not* the type specifier int.[/color]
                  >
                  > Thanks! I've printed out your post for later reference.
                  >[/color]

                  You might want to go with something a little more authoritative. ;-)

                  Seriously, get H&S, 5th edition, and study the grammar in Appendix B.
                  Declarations in C aren't quite as arbitrary as they appear at first
                  blush, but it helps to know *why* they are structured the way they are.
                  [color=blue]
                  > This part of C's declaration syntax borders upon insanity. I don't[/color]
                  care[color=blue]
                  > what *a is, I want to know the type of a itself! I only grokked what[/color]
                  was[color=blue]
                  > going on when I started writing "int *a" as "int * a", i.e. a itself[/color]
                  is a[color=blue]
                  > pointer to int. And now I know why no one writes that--because it[/color]
                  breaks[color=blue]
                  > down with the additional "declaratio n mimics use" paradigm.
                  >[/color]

                  Oh, yeah, declarators eat the big one. It took me over 10 years of
                  programming in C before I actually *understood* how they worked; it was
                  almost like getting an electric shock when I finally got it. Even now,
                  I read "int *a" as "a is a pointer to type int," instead of the more
                  correct "a is type pointer to int."

                  Yet more declarator fun (I think this is legit):

                  double (*(*(*(*f)(int x))[20])(double y, char (*z)(int h)))[100];

                  I think "insane" pretty much covers it.
                  [color=blue]
                  > Anybody would think the compiler's supposed to be omnipotent. How the[/color]
                  heck[color=blue]
                  > does "**a" mimic use if the majority of the time I'm only following[/color]
                  the[color=blue]
                  > first pointer, or passing a itself? It's an extra layer in the[/color]
                  declaration[color=blue]
                  > syntax that shouldn't be there!
                  >[/color]

                  It all has to do with the base type of the object. If you have an
                  object like

                  int **a;

                  then to get at the actual int value, you must use **a (or *a[i], or
                  a[i][j], depending). Of course, if you're only dealing with the
                  pointer itself, you're not going to be doing any dereferencing (such as
                  when you pass it to a function or something). But you still have to
                  declare it in terms of the base type.
                  [color=blue]
                  > Understand this explains a _lot_. I know why I've got to start[/color]
                  writing[color=blue]
                  > "int *a" instead of "int* a" or "int * a". In a saner world one would
                  > actually declare the type of a variable instead of also having to[/color]
                  second[color=blue]
                  > guess how it should look when used.
                  >
                  > Have fun,
                  > Adam[/color]

                  Well, you don't *have* to write "int *a" instead of "int* a" or "int *
                  a"; it just more accurately reflects what's happening in the grammar.

                  Comment

                  • Keith Thompson

                    #10
                    Re: Variable declaration syntax

                    john_bode@my-deja.com writes:
                    [...][color=blue]
                    > Yet more declarator fun (I think this is legit):
                    >
                    > double (*(*(*(*f)(int x))[20])(double y, char (*z)(int h)))[100];
                    >
                    > I think "insane" pretty much covers it.[/color]

                    I don't think any language has a declaration syntax that would make
                    that legible. The right thing to do with something like that is to
                    break it up into multiple typedefs with painfully obvious names.

                    --
                    Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
                    We must do something. This is something. Therefore, we must do this.

                    Comment

                    • thesushant@rediffmail.com

                      #11
                      Re: Variable declaration syntax

                      (*fp ) indicates its a pointer to function and the argument u r passing
                      is of void pointer type and the return type is void ..
                      Adam Warner wrote:[color=blue]
                      > Hi all,
                      >
                      > Just before Christmas Chris Torek gave me some great advice about[/color]
                      closures in C:[color=blue]
                      >[/color]
                      <http://groups.google.c o.nz/groups?selm=cqc l3k030vj%40news 3.newsguy.com&o utput=gplain>[color=blue]
                      >
                      > It includes this declaration of a function pointer variable called[/color]
                      fp:[color=blue]
                      > void (*fp)(void *);
                      >
                      > What does the syntax above mean? I can only digest it as void * fp,
                      > i.e. fp is a pointer to void.
                      >
                      > Thanks,
                      > Adam[/color]

                      Comment

                      Working...