const and compiler warning

Discussion in 'C Programming' started by bacbacdinner@gmail.com, Jun 12, 2008.

  1. Guest

    Can anyone explain to me why the code below generates a warning?
    /////////////////////////////////////////////////////////////
    typedef struct testStruct * TestStructRef;
    typedef TestStructRef * TestStructRefPtr;
    void func(const TestStructRefPtr data);

    /* code that uses above */
    const TestStructRef junk;
    func(&junk); /* compiler warning about different 'const' qualifier,
    here &junk is a pointer to a pointer */
    //////////////////////////////////////////////////////////////

    If I change it to use let say a 'char' instead of a struct I don't get
    a compiler warning.

    //////////////////////////////////////////////////////////////
    void func2(const char ** data);

    /* code that uses above */
    const char * junk;
    func2(&junk); /* no compiler warning, here &junk is a pointer to a
    pointer */
    ///////////////////////////////////////////////////////////////

    I'm seeing the warning with Visual Studio 2005. Sorry in advance if
    it's something obvious but I'm at a loss to explain it. Any help
    would be greatly appreciated.
     
    , Jun 12, 2008
    #1
    1. Advertising

  2. viza Guest

    Hi

    On Jun 12, 3:00 am, wrote:
    > Can anyone explain to me why the code below generates a warning?
    > /////////////////////////////////////////////////////////////
    > typedef struct testStruct * TestStructRef;
    > typedef TestStructRef * TestStructRefPtr;
    > void func(const TestStructRefPtr data);
    >
    > /* code that uses above */
    > const TestStructRef junk;
    > func(&junk); /* compiler warning about different 'const' qualifier,
    > here &junk is a pointer to a pointer */
    > //////////////////////////////////////////////////////////////
    >
    > If I change it to use let say a 'char' instead of a struct I don't get
    > a compiler warning.
    >
    > //////////////////////////////////////////////////////////////
    > void func2(const char ** data);
    >
    > /* code that uses above */
    > const char * junk;
    > func2(&junk); /* no compiler warning, here &junk is a pointer to a
    > pointer */
    > ///////////////////////////////////////////////////////////////


    I suggest:

    1: don't use CaMelCaps. It makes everything
    ReallyReallyDiffiCultToRead.

    2: don't typedef pointer types. typedef your struct, and then use *,
    which is universally understood.

    If you do this you may see the mistake that you have made. Hint:

    > here &junk is a pointer to a pointer */


    computer says no.

    Also,
    const TestStructRefPtr foo;
    means
    TestStructRef * const foo;

    which is almost certainly not what you mean. Again, you would not
    have made this mistake if you followed 2 above.

    HTH

    viza
     
    viza, Jun 12, 2008
    #2
    1. Advertising

  3. Guest

    On Jun 12, 4:32 am, viza <> wrote:
    > Hi
    >
    > On Jun 12, 3:00 am, wrote:
    >
    >
    >
    > > Can anyone explain to me why the code below generates a warning?
    > > /////////////////////////////////////////////////////////////
    > > typedef struct testStruct * TestStructRef;
    > > typedef TestStructRef * TestStructRefPtr;
    > > void func(const TestStructRefPtr data);

    >
    > > /* code that uses above */
    > > const TestStructRef junk;
    > > func(&junk); /* compiler warning about different 'const' qualifier,
    > > here &junk is a pointer to a pointer */
    > > //////////////////////////////////////////////////////////////

    >
    > > If I change it to use let say a 'char' instead of a struct I don't get
    > > a compiler warning.

    >
    > > //////////////////////////////////////////////////////////////
    > > void func2(const char ** data);

    >
    > > /* code that uses above */
    > > const char * junk;
    > > func2(&junk); /* no compiler warning, here &junk is a pointer to a
    > > pointer */
    > > ///////////////////////////////////////////////////////////////

    >
    > I suggest:
    >
    > 1: don't use CaMelCaps. It makes everything
    > ReallyReallyDiffiCultToRead.
    >
    > 2: don't typedef pointer types. typedef your struct, and then use *,
    > which is universally understood.
    >
    > If you do this you may see the mistake that you have made. Hint:
    >
    > > here &junk is a pointer to a pointer */

    >
    > computer says no.
    >
    > Also,
    > const TestStructRefPtr foo;
    > means
    > TestStructRef * const foo;
    >
    > which is almost certainly not what you mean. Again, you would not
    > have made this mistake if you followed 2 above.
    >
    > HTH
    >
    > viza


    Thanks for the reply. I have no choice as far as using CamelCase
    since that's the standard where I work. What I'm trying to do is call
    a function that returns a pointer to a constant structure. I changed
    the example using the advice you gave to:

    struct testStruct;
    typedef struct testStruct TestStruct;

    void func(const TestStruct ** data);

    const TestStruct * pData = 0;
    func(&pData);
     
    , Jun 12, 2008
    #3
  4. Ian Collins Guest

    wrote:
    > On Jun 12, 4:32 am, viza <> wrote:


    //////
    >> I suggest:
    >>
    >> 1: don't use CaMelCaps. It makes everything
    >> ReallyReallyDiffiCultToRead.
    >>
    >> 2: don't typedef pointer types. typedef your struct, and then use *,
    >> which is universally understood.
    >>
    >> If you do this you may see the mistake that you have made. Hint:
    >>


    >
    > Thanks for the reply. I have no choice as far as using CamelCase
    > since that's the standard where I work. What I'm trying to do is call
    > a function that returns a pointer to a constant structure.


    Camel case is just a common choice of style.

    The use of typedefs for pointer types is just bad style!

    --
    Ian Collins.
     
    Ian Collins, Jun 12, 2008
    #4
  5. santosh Guest

    Ian Collins wrote:

    [ ... ]

    > The use of typedefs for pointer types is just bad style!


    One might make an exception to that when constructing opaque data types.
    This is a situation where you want to hide the pointer nature and
    present it as a handle.
     
    santosh, Jun 12, 2008
    #5
  6. On Jun 12, 3:00 am, wrote:
    > Can anyone explain to me why the code below generates a warning?
    > /////////////////////////////////////////////////////////////
    > typedef struct testStruct *   TestStructRef;
    > typedef TestStructRef *  TestStructRefPtr;
    > void func(const TestStructRefPtr data);


    Function func has one parameter of type "TestStructRefPtr". The fact
    that you wrote "const" in front of it is completely pointless and
    doesn't mean anything, because qualifiers are ignored in a function
    declaration. If you used the same "const" in a function definition,
    then it would mean that the variable "data" is const and cannot be
    modified; for example, you wouldn't be allowed to write "data =
    NULL;".

    You seem to believe that "const TestStructRefPtr" is the same as
    "const TestStructRef *". It isn't. The former is a pointer to
    TestStructRef, and the pointer itself cannot be modified. The latter
    is a pointer to TestStructRef, and the TestStructRef pointed to cannot
    be modified.
     
    christian.bau, Jun 12, 2008
    #6
  7. Guest

    On Jun 12, 12:49 pm, "christian.bau"
    <> wrote:
    > On Jun 12, 3:00 am, wrote:
    >
    > > Can anyone explain to me why the code below generates a warning?
    > > /////////////////////////////////////////////////////////////
    > > typedef struct testStruct * TestStructRef;
    > > typedef TestStructRef * TestStructRefPtr;
    > > void func(const TestStructRefPtr data);

    >
    > Function func has one parameter of type "TestStructRefPtr". The fact
    > that you wrote "const" in front of it is completely pointless and
    > doesn't mean anything, because qualifiers are ignored in a function
    > declaration. If you used the same "const" in a function definition,
    > then it would mean that the variable "data" is const and cannot be
    > modified; for example, you wouldn't be allowed to write "data =
    > NULL;".
    >
    > You seem to believe that "const TestStructRefPtr" is the same as
    > "const TestStructRef *". It isn't. The former is a pointer to
    > TestStructRef, and the pointer itself cannot be modified. The latter
    > is a pointer to TestStructRef, and the TestStructRef pointed to cannot
    > be modified.


    The behavior I wanted was the latter. Thanks for the help, very much
    appreciated.
     
    , Jun 13, 2008
    #7
  8. Guest

    On Jun 12, 12:23 pm, santosh <> wrote:
    > Ian Collins wrote:
    >
    > [ ... ]
    >
    > > The use of typedefs for pointer types is just bad style!

    >
    > One might make an exception to that when constructing opaque data types.
    > This is a situation where you want to hide the pointer nature and
    > present it as a handle.


    The intent is to construct an opaque data type but it looks like using
    a typedef to a pointer isn't the way to go.
     
    , Jun 13, 2008
    #8
  9. writes:

    > On Jun 12, 12:23 pm, santosh <> wrote:
    >> Ian Collins wrote:
    >>
    >> [ ... ]
    >>
    >> > The use of typedefs for pointer types is just bad style!

    >>
    >> One might make an exception to that when constructing opaque data types.
    >> This is a situation where you want to hide the pointer nature and
    >> present it as a handle.

    >
    > The intent is to construct an opaque data type but it looks like using
    > a typedef to a pointer isn't the way to go.


    Then you may be giving up too early. If you need to point to a
    constant and typedef the whole lot (because you do want it to be just
    an opaque handle) you need to put the const into the typedef. You
    can't add constness to the to pointed-to type once the typedef is
    defined (as you discovered). Thus:

    typedef const struct my_hidden_struct *Handle;

    Allows one to declare, for example,

    void function(Handle h);

    and the struct pointed to by h is const. Of course, since the struct
    is opaque, your users can't get at the members pointed to by one of
    these handles, so all you gain by making it const is to prevent
    accidental copying like: '*h = *other_handle;'.

    --
    Ben.
     
    Ben Bacarisse, Jun 13, 2008
    #9
    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. Dylan
    Replies:
    5
    Views:
    332
    red floyd
    Aug 4, 2005
  2. Replies:
    14
    Views:
    711
    Kai-Uwe Bux
    Sep 18, 2006
  3. Replies:
    11
    Views:
    1,143
  4. Javier
    Replies:
    2
    Views:
    602
    James Kanze
    Sep 4, 2007
  5. 0m
    Replies:
    26
    Views:
    1,157
    Tim Rentsch
    Nov 10, 2008
Loading...

Share This Page