const qualifier and VC6.0

Discussion in 'C++' started by Sergey Tolstov, Oct 7, 2003.

  1. Hello,

    I am working with Visual C++ 6.0 compiler.

    In the following declaration:

    int const A = 10, B = 10;

    both A and B are const. However, in declaration

    int * const pA = SomePointer, pB;

    The pB is just int and not int * const. Is it VC++ compiler bug? What pB has
    to be according to C++ standard?


    Also, VC++ allows the following declaration of two int * const:

    int * const pB = SomePointerToInt, * const pA = SomePointerToInt;

    However it says in help file, that const type qualifier can appear only once
    in declaration. Where is the truth?

    Thanks,
    Sergey Tolstov
     
    Sergey Tolstov, Oct 7, 2003
    #1
    1. Advertising

  2. Sergey Tolstov

    Attila Feher Guest

    Sergey Tolstov wrote:
    > Hello,
    >
    > I am working with Visual C++ 6.0 compiler.
    >
    > In the following declaration:
    >
    > int const A = 10, B = 10;
    >
    > both A and B are const. However, in declaration
    >
    > int * const pA = SomePointer, pB;
    >
    > The pB is just int and not int * const. Is it VC++ compiler bug? What
    > pB has to be according to C++ standard?


    Not a bug. This is how the language works.

    > Also, VC++ allows the following declaration of two int * const:
    >
    > int * const pB = SomePointerToInt, * const pA = SomePointerToInt;
    >
    > However it says in help file, that const type qualifier can appear
    > only once in declaration. Where is the truth?


    Pointer declaratiosn contain two type. The type of what is pointed to, and
    the pointer itself.
    int *p;
    ptr to int

    const int *p;
    ptr to const int (does not mean the int is const, but cannot be modified via
    the ptr)

    int * const p;
    const ptr to int (the pointer itself cannot be modified, but the int it
    points to can)

    const int * const p;
    const ptr to const int (neither the pointer nor the valure pointed by it can
    be modified)


    --
    Attila aka WW
     
    Attila Feher, Oct 7, 2003
    #2
    1. Advertising

  3. Sergey Tolstov wrote:

    The trick is to see what the compiler is doing:
    > Hello,
    >
    > I am working with Visual C++ 6.0 compiler.
    >
    > In the following declaration:
    >
    > int const A = 10, B = 10;


    effectively, (int const) A = 10,B = 10;
    A and B const int.
    >
    > both A and B are const. However, in declaration
    >
    > int * const pA = SomePointer, pB;


    * is a unary operator returning the value at the address of the
    following argument,
    effectively: int (* const pA = somePointer),pB;

    pA const pointer to int (*pA must be initialized and contents can be
    altered!), pB a plain int!

    Consider the very misleading:
    int* a,b;
    a is pointer to int, b is int!

    effectively int (*a),b;

    Since the * operator is unary on the following address, it is better
    style (uh-oh ;-)) to write * with the variable than with the type:
    int *a,*b;
    >
    > The pB is just int and not int * const. Is it VC++ compiler bug? What pB has
    > to be according to C++ standard?
    >
    >
    > Also, VC++ allows the following declaration of two int * const:
    >
    > int * const pB = SomePointerToInt, * const pA = SomePointerToInt;
    >

    The effect is pB and pA are const pointer to non-const data, and the
    compiler will allow:
    *pA = 10;
    *pB = 5;
    but address assignment will be illegal:
    pA = &someInt;
    pB = &otherInt;

    const is misplaced. If const left of *, then data is constant, if right,
    then the pointer is constant, if both, then a constant pointer to
    constant data.

    You need to decide what is constant. From "Effective C++" by Scott Meyers:

    "For pointer, you can specify whether the pointer itself is const, the
    data it points to is const, both, or either:

    char *p = "Hello"; // non-const pointer, non-const data

    const char *p = "Hello"; // non-const pointer, const data

    char * const p = "Hello"; // const pointer, non-const data

    const char * const p = "Hello"; // const pointer, const data"

    You seem to want non-const pointer to const data:

    const int *pA,*pB; // Note no initialization required!

    or const pointer to const data:
    const int * const pA = ...,* const pB = ...;
    effectively (const int)(* const pa = ...),(* const pB = ...); // Since *
    must be used for each pointer, so must the corresponding const.

    > However it says in help file, that const type qualifier can appear only once
    > in declaration. Where is the truth?


    >
    > Thanks,
    > Sergey Tolstov
    >
    >


    Regards
    Andrew
     
    Andrew Morgan, Oct 7, 2003
    #3
  4. Sergey Tolstov

    tom_usenet Guest

    On Tue, 07 Oct 2003 13:12:00 +0200, Andrew Morgan
    <> wrote:

    >Since the * operator is unary on the following address, it is better
    >style (uh-oh ;-)) to write * with the variable than with the type:
    >int *a,*b;


    The inevitable bite:

    In C++ it is better to put the * with the type, since in C++ the
    emphasis is on types, while in C the emphasis is on expressions. It is
    also important that you only use one pointer or reference declaration
    per line.

    int* p, j; //bad!

    int* i; //good
    int j; //good

    (FWIW, Stroustrup uses this style)

    Tom
     
    tom_usenet, Oct 7, 2003
    #4
  5. Sergey Tolstov

    Attila Feher Guest

    tom_usenet wrote:
    > On Tue, 07 Oct 2003 13:12:00 +0200, Andrew Morgan
    > <> wrote:
    >
    >> Since the * operator is unary on the following address, it is better
    >> style (uh-oh ;-)) to write * with the variable than with the type:
    >> int *a,*b;

    >
    > The inevitable bite:
    >
    > In C++ it is better to put the * with the type, since in C++ the
    > emphasis is on types, while in C the emphasis is on expressions. It is
    > also important that you only use one pointer or reference declaration
    > per line.
    >
    > int* p, j; //bad!
    >
    > int* i; //good
    > int j; //good
    >
    > (FWIW, Stroustrup uses this style)


    Dan Saks (worked with Stroustup on the language) suggests to use the style
    which reflects the semantics of the language:

    int *p, j; //bad, but visibly!

    int *i; //good
    int j;

    --
    Attila aka WW
     
    Attila Feher, Oct 7, 2003
    #5
  6. Sergey Tolstov

    Jerry Coffin Guest

    In article <nftgb.54627$>,
    says...
    > Hello,
    >
    > I am working with Visual C++ 6.0 compiler.


    You might want to consider updating your compiler -- this one came out
    well before the standard, so there are substantial parts of the standard
    that it doesn't attempt to implement. With that said, however...

    > In the following declaration:
    >
    > int const A = 10, B = 10;
    >
    > both A and B are const. However, in declaration
    >
    > int * const pA = SomePointer, pB;
    >
    > The pB is just int and not int * const. Is it VC++ compiler bug? What pB has
    > to be according to C++ standard?


    In this area it's absolutely correct. If you switched the two items
    around:

    int pB, *const pA = SomePointer;

    you'd still be defining the same things.

    > Also, VC++ allows the following declaration of two int * const:
    >
    > int * const pB = SomePointerToInt, * const pA = SomePointerToInt;
    >
    > However it says in help file, that const type qualifier can appear only once
    > in declaration. Where is the truth?


    The help file you're reading is doing a poor job of expressing the idea,
    and the compiler is doing the right thing. When you define more than
    one object, you can apply const to each perfectly legitimately. You can
    even use const more than once in defining a single object:

    int const * const x;

    for one example, is well-formed. What you can't do is directly apply
    const twice, as in something like:

    int const const x = 1 ; // ill-formed.

    If, however, the const-ness gets introduced a second time because of
    something like a template, it's usually allowed:

    template<class T>
    struct X {

    void f(T const &t) { }
    };

    X<char const x> y;

    Taken literally, this _would_ mean that the argument to f is a reference
    to a const const char, but in fact the extra const is simply ignored.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Oct 7, 2003
    #6
  7. tom_usenet wrote:

    > On Tue, 07 Oct 2003 13:12:00 +0200, Andrew Morgan
    > <> wrote:
    >
    >
    >>Since the * operator is unary on the following address, it is better
    >>style (uh-oh ;-)) to write * with the variable than with the type:
    >>int *a,*b;

    >
    >
    > The inevitable bite:
    >
    > In C++ it is better to put the * with the type, since in C++ the
    > emphasis is on types, while in C the emphasis is on expressions. It is
    > also important that you only use one pointer or reference declaration
    > per line.


    This is a self-imposed restriction, since the compiler could not care
    less about:
    int a,*b,**c;

    >
    > int* p, j; //bad!
    >
    > int* i; //good
    > int j; //good



    I have no intentional of being drawn into a controversy, so my only
    response will be to quote verbatim from "C++ The Complete Reference, 3rd
    Edition" by Herbert Schildt:

    "A Matter of Style
    ------------------
    When declaring pointer and reference variables, some C++ programmers use
    a unique coding style that associates the * or the & with the type name
    and not the variable. For example, here are two functionally equivalent
    declarations:

    int& p; // & associated with type
    int &p; // & associated with variable

    Associating the * or & with the type name reflects the desire of some
    programmers for C++ to contain a separate pointer type. However, the
    trouble with associating the & or * with the type name rather than the
    variable is that, according to the formal C++ syntax, neither the & nor
    the * is distributive over a list of variables. Thus, misleading
    declarations are easily created. For example, the following declaration
    creates one, not two, integer pointers.

    int* a,b;

    Here, b is declared as an integer (not an integer pointer) because,
    as specified by the C++ syntax, when used in a declaration, the * (or &)
    is linked to the individual variable that it precedes, not to the type
    that it follows. The trouble with this declaration is that the visual
    message suggests that both a and b are pointer types, even though, in
    fact, only a is a pointer. This visual confusion not only misleads
    novice C++ programmers, but occasionally old pros, too.

    It is important to understand that, as far as the C++ compiler is
    concerned, it doesn't matter whether you write int *p or int* p. Thus
    if you prefer to associate the * or & with the type rather than the
    variable, feel free to do so. However, to avoid confusion, this book
    will continue to associate the * and the & with the variables that they
    modify rather than their types."
    >
    > (FWIW, Stroustrup uses this style)
    >
    > Tom


    It is simply a matter of style I and do not think that people should be
    berated for a style preference. FWIW many of the great C++ authors like
    Scott Meyers, Herbert Schildt and James Coplien use the int *a style,
    which others like Herb Sutter, Nicolai Josuttis and Andrei Alexandrescu
    use int* a.

    Andrew
     
    Andrew Morgan, Oct 7, 2003
    #7
  8. Sergey Tolstov

    Attila Feher Guest

    Andrew Morgan wrote:
    > I have no intentional of being drawn into a controversy, so my only
    > response will be to quote verbatim from "C++ The Complete Reference,
    > 3rd Edition" by Herbert Schildt:


    Don't! Please oh don't quote Schildt here. Should we extend Godwin's law?

    --
    Attila aka WW
     
    Attila Feher, Oct 7, 2003
    #8
  9. Sergey Tolstov

    Howard Guest

    "Andrew Morgan" <> wrote in message
    news:blu728$bat$...
    > Sergey Tolstov wrote:
    >
    > ..., in declaration
    > >
    > > int * const pA = SomePointer, pB;

    >
    > * is a unary operator returning the value at the address of the
    > following argument,
    > effectively: int (* const pA = somePointer),pB;
    >
    > pA const pointer to int (*pA must be initialized and contents can be
    > altered!), pB a plain int!
    >


    The above statement doesn't make sense to me. You say the * in the above
    statement is a unary operator (the dereference operator, I assume)? It's
    not an operator at all in this case, but part of the declaration. It
    declares pA to be of type int* (a pointer-to-int). It does not return
    anything. This is a declaration (actually two declarations, the second
    being "int pB"), with an initialization (the value of SomePointer). The end
    result is as you describe, but the reason is different.

    -Howard
     
    Howard, Oct 7, 2003
    #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. Javier
    Replies:
    2
    Views:
    624
    James Kanze
    Sep 4, 2007
  2. Ben Petering

    const type qualifier and external linkage (term.?)

    Ben Petering, Dec 30, 2007, in forum: C Programming
    Replies:
    7
    Views:
    462
    Thad Smith
    Dec 31, 2007
  3. Replies:
    12
    Views:
    858
    Old Wolf
    Dec 14, 2008
  4. paulo
    Replies:
    9
    Views:
    742
    James Kanze
    Mar 6, 2009
  5. Frédéric Kpama

    const qualifier and pointers

    Frédéric Kpama, Dec 28, 2011, in forum: C Programming
    Replies:
    5
    Views:
    443
    Kaz Kylheku
    Dec 29, 2011
Loading...

Share This Page