Declarator question

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

    Declarator question

    Sorry in advance if this is really dumb, but I am trying to get my
    head around exactly what the declarator is. In the FAQ, 1.21, part of
    it says "C declarations ....come in 2 parts, a base type and a
    declarator..... .".

    The example used is char *pc where the declarator " *pc" tells us
    that " *pc is a character".

    Can one thus broadly say that a declarator is in fact equivalent to
    the base type?

    So, in a more complicated expression eg char * ( *pfpc) () ; once
    again "* ( *pfpc) ()" is a character?

    Thanks as usual.
  • Eric Sosman

    #2
    Re: Declarator question

    mdh wrote:
    Sorry in advance if this is really dumb, but I am trying to get my
    head around exactly what the declarator is. In the FAQ, 1.21, part of
    it says "C declarations ....come in 2 parts, a base type and a
    declarator..... .".
    >
    The example used is char *pc where the declarator " *pc" tells us
    that " *pc is a character".
    >
    Can one thus broadly say that a declarator is in fact equivalent to
    the base type?
    In `char *pc' the base type is `char' and the declarator is
    `*pc'. The declaration -- both pieces taken together -- says that
    the declarator has the base type: in this case, `*pc' has the
    type `char'. Later in the program, any place you write `*pc' you
    have written an expression whose type is `char'.
    So, in a more complicated expression eg char * ( *pfpc) () ; once
    again "* ( *pfpc) ()" is a character?
    Yes. An expression that looks like the declarator has a type,
    and that type is the base type from the declaration.

    --
    Eric.Sosman@sun .com

    Comment

    • mdh

      #3
      Re: Declarator question

      On Jul 16, 10:54 am, Eric Sosman <Eric.Sos...@su n.comwrote:
      >
           In `char *pc' the base type is `char' and the declarator is
      `*pc'.  The declaration -- both pieces taken together -- says that
      the declarator has the base type: in this case, `*pc' has the
      type `char'.  Later in the program, any place you write `*pc' you
      have written an expression whose type is `char'.
      >
      >

      thanks Eric. A little more probing.
      Now if one adds a qualifyer like 'const' as in 'const char' etc,is the
      type now 'const char' ?




      Comment

      • Eric Sosman

        #4
        Re: Declarator question

        mdh wrote:
        On Jul 16, 10:54 am, Eric Sosman <Eric.Sos...@su n.comwrote:
        >
        > In `char *pc' the base type is `char' and the declarator is
        >`*pc'. The declaration -- both pieces taken together -- says that
        >the declarator has the base type: in this case, `*pc' has the
        >type `char'. Later in the program, any place you write `*pc' you
        >have written an expression whose type is `char'.
        >>
        >>
        >
        >
        thanks Eric. A little more probing.
        Now if one adds a qualifyer like 'const' as in 'const char' etc,is the
        type now 'const char' ?
        Yes; it's a "qualified type." The type qualifiers are
        const, volatile, and (new in C99) restrict, and they can be
        used alone, in combination, or (of course) not at all.

        --
        Eric Sosman
        esosman@ieee-dot-org.invalid

        Comment

        • pete

          #5
          Re: Declarator question

          mdh wrote:
          Sorry in advance if this is really dumb, but I am trying to get my
          head around exactly what the declarator is. In the FAQ, 1.21, part of
          it says "C declarations ....come in 2 parts, a base type and a
          declarator..... .".
          >
          The example used is char *pc where the declarator " *pc" tells us
          that " *pc is a character".
          >
          Can one thus broadly say that a declarator is in fact equivalent to
          the base type?
          I would go so far as to say that the declarator is an lvalue
          of the base type.

          --
          pete

          Comment

          • mdh

            #6
            Re: Declarator question

            On Jul 16, 3:26 pm, pete <pfil...@mindsp ring.comwrote:
            mdh wrote:
            Sorry in advance if this is really dumb, but I am trying to get my
            head around exactly what the declarator is. In the FAQ, 1.21, part of
            it says "C declarations ....come in 2 parts, a base type and a
            declarator..... .".
            >
            The example used is char *pc where the declarator  " *pc" tells us
            that " *pc is a character".
            >
            Can one thus broadly say that a declarator is in fact equivalent to
            the base type?
            >
            I would go so far as to say that the declarator is an lvalue
            of the base type.
            >
            --
            pete
            Thanks Pete and Eric.

            Comment

            • John Bode

              #7
              Re: Declarator question

              On Jul 16, 12:25 pm, mdh <m...@comcast.n etwrote:
              Sorry in advance if this is really dumb, but I am trying to get my
              head around exactly what the declarator is. In the FAQ, 1.21, part of
              it says "C declarations ....come in 2 parts, a base type and a
              declarator..... .".
              >
              The example used is char *pc where the declarator " *pc" tells us
              that " *pc is a character".
              >
              Can one thus broadly say that a declarator is in fact equivalent to
              the base type?
              >
              So, in a more complicated expression eg char * ( *pfpc) () ; once
              again "* ( *pfpc) ()" is a character?
              >
              Thanks as usual.
              Pete and Eric have given you good answers, but I'd like to add a few
              things.

              The declarator introduces the name of the thing being declared (pc)
              and any additional type information not provided by the type specifier
              "char". In this case, the "pointernes s" of pc is provided by the
              declarator *pc.

              Remember that in C, declaration mimics use. If I have a pointer to a
              character, I retrieve the character value by dereferencing the pointer
              like so:

              c = *pc;

              Thus, the expression "*pc" evaluates to a char value. So, going by
              the "declaratio n mimics use" rule, the declaration for a pointer to
              char is

              char *pc;

              Remember that the '*' is bound to the identifier, not the type
              specifier, regardless of any whitespace. "char* pc;" is the same as
              "char * pc;" and "char *pc;". If you wrote

              char* pc1, pc2;

              only pc1 would be declared as a pointer to char; pc2 would be a
              regular char.

              Array types are similar. If I want to retrieve a specific character
              value from an array of char, I use the subscript operator:

              c = ac[i];

              Again, the type of the expression "ac[i]" is char, so the declaration
              for an array of char is

              char ac[N];

              Your function pointer also follows this rule. If I have a pointer to
              a function that returns a pointer to a char, I retrieve that char
              value by calling that function (using the dereferenced function
              pointer), and then dereference the value returned by the function,
              like so:

              c = *(*pfpc)();

              Hence the declaration

              char *(*pfpc)();

              When you come across a hairier than normal declarator, the way to read
              it is to find the leftmost identifier, then work your way out,
              remembering that () and [] bind before * (IOW, *a[] is an array of
              pointer, not a pointer to an array). Using pfpc as an example:

              pfpc -- pfpc
              *pfpc -- is a pointer
              (*pfpc)() -- to a function
              *(*pfpc)() -- returning a pointer
              char *(*pfpc)() -- to char.

              Note that the type qualifier "typedef" changes things a little. In
              the declaration

              typedef char *(*pfpc)();

              pfpc is not an instance of a pointer to a function to a pointer to
              char, but is rather a synonym for the *type* "pointer to a function
              returning pointer to char". You could use the typedef to make some
              declarations easier to read:

              typedef char *charptr; // charptr is a synonym for "char *"
              typedef charptr (*fptr)(); // fptr is a synonym for charptr (*)()
              fptr myptr; // myptr is a pointer to a function
              // returning a pointe to char

              although I tend not to do this, as typedefs sometimes obscure more
              that they illuminate.

              Comment

              • santosh

                #8
                Re: Declarator question

                John Bode wrote:

                <snip>
                Remember that in C, declaration mimics use. If I have a pointer to a
                character, I retrieve the character value by dereferencing the pointer
                like so:
                >
                c = *pc;
                >
                Thus, the expression "*pc" evaluates to a char value. So, going by
                the "declaratio n mimics use" rule, the declaration for a pointer to
                char is
                >
                char *pc;
                Sometimes I wish that C had used a specific type specifier to declare
                pointers like say 'ptr' as in:

                ptr long lp = &some_long_obje ct;

                Then we could've done this:

                some_other_long _obj = lp;

                and perhaps reserved *lp to access value of lp itself.

                So much more code deferences pointers than manipulating their values
                that this syntax would've led to a more "cleaner" code, IMHO. But OTOH
                it would've hidden the fact that an indirection is taking place. Oh
                well, it three decades too late now...

                <rest of excellent explanations snipped>

                Comment

                • mdh

                  #9
                  Re: Declarator question

                  On Jul 17, 9:34 am, John Bode <jfbode1...@gma il.comwrote:
                  >
                  >
                  Pete and Eric have given you good answers, but I'd like to add a few
                  things.
                  John, I can only quote Santosh and say thank you for those "excellent
                  explanations".


                  Comment

                  • Jack Klein

                    #10
                    Re: Declarator question

                    On Thu, 17 Jul 2008 22:45:02 +0530, santosh <santosh.k83@gm ail.com>
                    wrote in comp.lang.c:
                    John Bode wrote:
                    >
                    <snip>
                    >
                    Remember that in C, declaration mimics use. If I have a pointer to a
                    character, I retrieve the character value by dereferencing the pointer
                    like so:

                    c = *pc;

                    Thus, the expression "*pc" evaluates to a char value. So, going by
                    the "declaratio n mimics use" rule, the declaration for a pointer to
                    char is

                    char *pc;
                    >
                    Sometimes I wish that C had used a specific type specifier to declare
                    pointers like say 'ptr' as in:
                    >
                    ptr long lp = &some_long_obje ct;
                    >
                    Then we could've done this:
                    >
                    some_other_long _obj = lp;
                    >
                    and perhaps reserved *lp to access value of lp itself.
                    >
                    So much more code deferences pointers than manipulating their values
                    that this syntax would've led to a more "cleaner" code, IMHO. But OTOH
                    it would've hidden the fact that an indirection is taking place. Oh
                    well, it three decades too late now...
                    No, a thousand times NO!!!

                    That is actually one of the problem with C++ references. If you are
                    not looking at the prototype, does:

                    int x = 42;
                    some_cpp_func(x );

                    ....pass 'x' by value, making the caller's int immune to changes?

                    ....pass 'x' by non constant reference, allowing the function to change
                    the caller's object?

                    ....pass 'x' by constant reference, making the caller's int immune to
                    changes?

                    Well, which is it???

                    But even worse, it brings HORRIBLE FLASH BACKS TO PL/M!!!

                    declare pointer address;
                    declare data byte based address;

                    The worst of all possible worlds!

                    The declaration of the pointer object itself does not tell you that
                    it's a pointer (in PL/M 80, the one and only 16-bit data type, an
                    unsigned integer type that also happened to be compatible with a
                    pointer, had type 'address', even if you only wanted to use it as an
                    int).

                    The pointed-to object was accessed by its own name, with no obvious
                    relationship to the pointer.

                    You can take away my asterisk when you rip it out of my cold, dead
                    hands.

                    --
                    Jack Klein
                    Home: http://JK-Technology.Com
                    FAQs for
                    comp.lang.c http://c-faq.com/
                    comp.lang.c++ http://www.parashift.com/c++-faq-lite/
                    alt.comp.lang.l earn.c-c++

                    Comment

                    • David Thompson

                      #11
                      Re: Declarator question

                      On Wed, 16 Jul 2008 18:26:01 -0400, pete <pfiland@mindsp ring.com>
                      wrote:
                      mdh wrote:
                      Sorry in advance if this is really dumb, but I am trying to get my
                      head around exactly what the declarator is. In the FAQ, 1.21, part of
                      it says "C declarations ....come in 2 parts, a base type and a
                      declarator..... .".

                      The example used is char *pc where the declarator " *pc" tells us
                      that " *pc is a character".

                      Can one thus broadly say that a declarator is in fact equivalent to
                      the base type?
                      >
                      I would go so far as to say that the declarator is an lvalue
                      of the base type.
                      Sort of, but not exactly, nor completely.

                      In general a declarator is not an expression, only similar to it.

                      For a pointer declarator T *p, *p is indeed a T lvalue, assuming p has
                      been set to a valid nonnull value i.e. a pointer to a T object.
                      (And for T * f(parms?) if f(args) returns such a value.)

                      For an array declarator T a[6], a[0] or a[5] is, but not a[6].

                      For a function declarator T f(int,double), f(1, 2.3) is a T _rvalue_
                      not an lvalue.

                      - formerly david.thompson1 || achar(64) || worldnet.att.ne t

                      Comment

                      Working...