Topic: Const


Author: fenster@shadow.cs.columbia.edu (Sam Fenster)
Date: 1995/06/07
Raw View
kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:
> fenster@shadow.cs.columbia.edu (Sam Fenster) writes:
>> `const' before the specifier would be allowed in a separate part of the
>> grammar, and would be semantically equivalent to preceding each of the
>> declarators with `const'.
>
> This would introduce some sort of ordering in the specifier list, since
> `const' could not be the final element.

Nope!  Notice that I didn't say, "`const' IN the specifier."  I said, "`const'
BEFORE the specifier."

>>> In addition, it would probably make it awkward for C++'s `const' defaults
>>> to static linkage rule (since the storage class is part of the specifier).

>> Doesn't `int *const p;' default to static linkage?  I hope the static
>> linkage rule applies to all named const objects.  I hope it doesn't depend
>> on which of its two syntactic roles const is playing.

And, I forgot to mention, doesn't `const int *p;' default to external linkage?
(At file scope, of course.)  So whether `const' is in the specifier or one of
the declarators is unrelated to whether the things it declares default to
static linkage at file scope.

> Good point.  This leads to an interesting situation:
>  int *const p1 , *p2 ;
> In the above, p1 is static, p2 no.  (Yeck!).

Whoah!  Is that true?  Anyone?  Yucchhh.

> IMHO, the C/C++ declaration syntax is so broken that no little fix-up
> will suffice.  It would take a completely new design to clean it up.

I would eliminate the "const defaults to static at file scope" rule.  People
can type "static" if that's what they want.

On second thought, I'd make *everything* default to internal linkage unless
otherwise declared.  Also, I'd make the syntax for declaring `int i;' be
different from the syntax for *defining* `int i;'





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/08
Raw View
In article <FENSTER.95Jun7171649@shadow.cs.columbia.edu>
fenster@shadow.cs.columbia.edu (Sam Fenster) writes:

|> kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:
|> > fenster@shadow.cs.columbia.edu (Sam Fenster) writes:
|> >> `const' before the specifier would be allowed in a separate part of the
|> >> grammar, and would be semantically equivalent to preceding each of the
|> >> declarators with `const'.
|> >
|> > This would introduce some sort of ordering in the specifier list, since
|> > `const' could not be the final element.

|> Nope!  Notice that I didn't say, "`const' IN the specifier."  I said, "`const'
|> BEFORE the specifier."

Thus? const static int ...

Most people I've seen actually place the storage class specifier
first.

What you are thus proposing is basically to add a third part to the
declaration:

 declaration <- [<global-cv-qual>] <decl-specifier> <declarator-list>

|> >>> In addition, it would probably make it awkward for C++'s `const' defaults
|> >>> to static linkage rule (since the storage class is part of the specifier).

|> >> Doesn't `int *const p;' default to static linkage?  I hope the static
|> >> linkage rule applies to all named const objects.  I hope it doesn't depend
|> >> on which of its two syntactic roles const is playing.

|> And, I forgot to mention, doesn't `const int *p;' default to external linkage?
|> (At file scope, of course.)  So whether `const' is in the specifier or one of
|> the declarators is unrelated to whether the things it declares default to
|> static linkage at file scope.

Correct.  In fact, it is necessary to analyse the type completely: if
the top level type is const, the storage class defaults to static,
otherwise to extern-definition.

|> > Good point.  This leads to an interesting situation:
|> >  int *const p1 , *p2 ;
|> > In the above, p1 is static, p2 no.  (Yeck!).

|> Whoah!  Is that true?  Anyone?  Yucchhh.

I, too, would like confirmation by one of the other experts (Fergus?,
Steve?).  But it would seem that this is the implication of the above
rule.

Yet another reason to only use one declarator per declaration.

|> > IMHO, the C/C++ declaration syntax is so broken that no little fix-up
|> > will suffice.  It would take a completely new design to clean it up.

|> I would eliminate the "const defaults to static at file scope" rule.  People
|> can type "static" if that's what they want.

|> On second thought, I'd make *everything* default to internal linkage unless
|> otherwise declared.  Also, I'd make the syntax for declaring `int i;' be
|> different from the syntax for *defining* `int i;'

Agreed.  In sum, a major design change:-).

Actually, it would be fairly easy to do all but the last (different
syntax for declarations and definitions).  It would also break almost
all existing programs:-(.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: fenster@shadow.cs.columbia.edu (Sam Fenster)
Date: 1995/06/07
Raw View
>>> Ron Hunsinger (hnsngr@sirius.com) wrote:
>>>>   char * const p, * q;
>>>> p is const, q is not. But what about
>>>>   char const *p, *q;
>>>> p points to const char. What does q point to? char, or const char?

>> kanze@gabi-soft.fr (J. Kanze) writes:
>>> const char.

> Sam Fenster (fenster@shadow.cs.columbia.edu) wrote:
>> Pretty ugly and unintuitive, right?  All of a sudden, `const' is glued to
>> `char' (the type specifier) instead of to `*p' (the first declarator), when
>> it could still meaningfully be part of the declarator.  A badly-designed
>> piece of the C/C++ grammar.

kanze@gabi-soft.fr (J. Kanze) writes:
> According to the C/C++ grammar, `const' cannot meaningfully be part of the
> declarator here[...] If your point is simply that the C/C++ grammar for
> declarations is not particularly well-designed, you'll get no disagreement
> from me:-).  Given the way the grammar works (and worked, before const), I
> don't really see any other way which const could fit in, however.

I was indeed criticizing the grammar.  Const *could* have fit in as follows:

> I think I see what you are getting at.  You would like for `const' to be a
> modifier, much like `*', rather than a qualifier.

Yes.  This would allow the currently illegal -- but perfectly sensible -- `int
*p, const *q;' and `int *(const *p);'.

> Done consequentially, this wouldn't allow `const' at all in the specifier
> (since no modifiers are allowed in the specifier), thus banning:
>  const int i;

`const' before the specifier would be allowed in a separate part of the
grammar, and would be semantically equivalent to preceding each of the
declarators with `const'.

Thus, `int const *p, *q;' would declare *p as const, but not *q.  `const int
*p, *q;' would be different syntax -- it would make them both const.

> In addition, it would probably make it awkward for C++'s `const' defaults to
> static linkage rule (since the storage class is part of the specifier).

Doesn't `int *const p;' default to static linkage?  I hope the static linkage
rule applies to all named const objects.  I hope it doesn't depend on which of
its two syntactic roles const is playing.





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/07
Raw View
In article <FENSTER.95Jun7003209@shadow.cs.columbia.edu>
fenster@shadow.cs.columbia.edu (Sam Fenster) writes:

|> `const' before the specifier would be allowed in a separate part of the
|> grammar, and would be semantically equivalent to preceding each of the
|> declarators with `const'.

This would introduce some sort of ordering in the specifier list,
since `const' could not be the final element.  Unless the list is
changed to be fully ordered (which would break a lot of C/C++
programs), your rule would drive compiler writers up the wall.
Consider:

 int const static ...

The compiler cannot know whether the const is part of the specifier or
part of the declarator until it sees the following keyword.  (In
compiler theory terms, the compiler has no way of determining whether
to shift or to reduce when it encounters the `const' in the above.  It
requires an additional token of look-ahead.)

|> Thus, `int const *p, *q;' would declare *p as const, but not *q.  `const int
|> *p, *q;' would be different syntax -- it would make them both const.

|> > In addition, it would probably make it awkward for C++'s `const' defaults to
|> > static linkage rule (since the storage class is part of the specifier).

|> Doesn't `int *const p;' default to static linkage?  I hope the static linkage
|> rule applies to all named const objects.  I hope it doesn't depend on which of
|> its two syntactic roles const is playing.

Good point.  This leads to an interesting situation:

 int *const p1 , *p2 ;

In the above, p1 is static, p2 no.  (Yeck!).

IMHO, the C/C++ declaration syntax is so broken that no little fix-up
will suffice.  It would take a completely new design to clean it up.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: shepherd@debussy.sbi.com (Marc Shepherd)
Date: 1995/06/07
Raw View
In article 9p8@info.physics.utoronto.ca, peter@chinook.physics.utoronto.ca (Peter Berdeklis) writes:
>According to Marc Shepherd <shepherd@debussy.sbi.com>:
>>'const int const *p' is redundant--both 'consts' constrain
>> the integer, not the pointer.  The syntax meeting your description is:
>> 'const int * const p' or 'int const * const p' -- take your pick.
>   ^^^^^^^^^^^^^^^^^^^      ^^^^^^^^^^^^^^^^^^^
>
>Is 'int const * p const' correct, and does it mean the same as the ex.'s
>underlined above?

No, 'int const * p const' is a syntax error.

>
>As I read it, the first const modifies the int, and the second modifies
>the p, regardless of whether the const is before or after the int or the p.
>Nothing (really) modifies the *, which is the cause of all the confusion
>since 'int const const p' would obviously be redundant.
>
>Is this correct?

No.  In the declaration 'int const * const p', the first 'const' constrains
the int, the second 'const' constrains the pointer.  This is still true if
you change it to 'const int * const p'.  The only way to constrain the pointer
(as opposed to the value it points to) is for the 'const' to come after the
'*'.


---
Marc Shepherd
Salomon Brothers Inc
shepherd@schubert.sbi.com The opinions I express are no one's but mine!






Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/07
Raw View
In article <1995Jun3.130041.14670@walter.cray.com>
glover@hikimi.cray.com (Roger Glover) writes:

|> In article <KANZE.95Jun1122843@slsvhdt.lts.sel.alcatel.de>, kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:
|> > In article <3qhsaj$i43@watnews2.watson.ibm.com> jjb@watson.ibm.com
|> > (John Barton) writes:

|> [some stuff omitted]

|> > |> C++ declarations just don't read from left to right; neither do
|> > |> expressions:
|> > |>    x = (*fp)(y);  // assignment happens after the function evaluation.
|> >
|> > Correct.  And the only solution I've found so far is to consider the
|> > declaration a type expression, and parse it like an expression, with
|> > full respect for precedence and binding.

|> > Oh well, if it were easy, it wouldn't be C++:-).

|> So, if I may summarize, parsing declarations is like parsing
|> executable expressions *in reverse*.  In parsing an executable
|> expression you:
|>  - start with the identifier
|>  - work your way out of the expression
|>    -- in order of precedence
|>    -- with parenthetical subexpressions evaluated first

|> In parsing a declaration, you:
|>  - start outside the expression
|>  - work your way in to the identifier (peeling off the
|>    operators like onion skin)
|>    -- in *reverse* order of precedence
|>    -- with parenthetical subexpressions evaluated *last*

I tend to do parse the declarations exactly like an expression, e.g.:

 int *fp() ;

Start with the identifier: "fp is".  `()' has precedence over `*', so
it is next: a function returning.  With the above: "fp is a function
returning".  Next comes `*': "fp is a function returning a pointer
to".  Finally, the specifier: "fp is a function returning a pointer to
int".

This works well within the declarator.  To extend it to the specifier,
it is necessary to remember that the specifier is an unordered list,
and simply treat it as a unit, no matter how many words it contains.
(You can rearrange the words as you like in order to make the English
equivalent readable.  Just don't forget that any modifiers in the
specifier can only affect the base type.)

|> There are some examples below.

|> Examples:

|>     int *fp();

|>  - "*fp()" is an int, so
|>  - "fp()" is a pointer to int, so
|>  - "fp" is a function returning pointer to int

 - fp: "fp is"
 - (): "a function returning"
 - *: "a pointer to"
 - int: "an int"

|>     int (*fp)();

|>  - "(*fp)()" is an int, so
|>  - "(*fp)" is a function returning int, so
|>  - "fp" is a pointer to a function returning int

 - fp: "fp is"
 - *: "a pointer to"
 - (): "a function returning"
 - int: "an int"

|>     int *fp[5];

|>  - "*fp[5]" is an int, so
|>  - "fp[5]" is a pointer to int, so
|>  - "fp" is an array of 5 pointers to int

 - fp "fp is"
 - [5] "an array[5] of"
 - * "pointer to"
 - int "int"

|>     int (*fp)[3][5];

|>  - "(*fp)[3][5]" is an int, so
|>  - "(*fp)[3]" is an array of 5 ints, so
|>  - "*fp" is an array of 3 arrays of 5 ints, so
|>  - "fp" is a pointer to an array of 3 arrays of 5 ints

 - fp "fp is"
 - * "a pointer to"
 - [3]  "an array[3] of"
 - [5] "an array[5] of"
 - int "int"

|> Now with const:

|>     const int **pp;

|>  - "**pp" is a constant int, so
|>  - "*pp" is a pointer to constant int, so
|>  - "pp" is a pointer to pointer to constant int

 - pp "pp is"
 - * "a pointer to"
 - * "a pointer to"
 - const int:
 "a const int"

(Note that the specifier is processed as a unit.)

|>     int * const *pp;

|>  - "* const *pp" is an int, so
|>  - "*pp" is a constant pointer to an int, so
|>  - "pp" is a pointer to a constant pointer to an int

 - pp "pp is"
 - * "a pointer to"
 - const "a const"
 - * "pointer to"
 - int "an int"

|>     int ** const pp;

|>  - "** const pp" is an int, so
|>  - "* const pp" is a pointer to an int, so
|>  - "pp" is a constant pointer to a pointer to an int

 - pp "pp is"
 - const "a const"
 - * "pointer to"
 - * "a pointer to"
 - int "an int"

I think if you study it carefully, you will see that we are in fact
doing the same thing.  I'm working bottom up, and you are analysing
top down.  In both cases, we are basically parsing an expression.  (A
bit of declaration mimics use, although things like typedef and const
introduce their own rules into the type expression.)
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/07
Raw View
In article <D9ro1p.9p8@info.physics.utoronto.ca>
peter@chinook.physics.utoronto.ca (Peter Berdeklis) writes:

|> According to Marc Shepherd <shepherd@debussy.sbi.com>:
|> >'const int const *p' is redundant--both 'consts' constrain
|> > the integer, not the pointer.  The syntax meeting your description is:
|> > 'const int * const p' or 'int const * const p' -- take your pick.
|>    ^^^^^^^^^^^^^^^^^^^      ^^^^^^^^^^^^^^^^^^^

|> Is 'int const * p const' correct, and does it mean the same as the ex.'s
|> underlined above?

No.  Read some of my other postings.  In the declarator, the const
*follows* what it modifies (in the type).  In the underlined examples,
the second const qualifies the `*'.  (The `p' is not really part of
the type expression; the const acts as a modifier within the type
expression.)

Note that something like:
 int const* f() const ;
is legal.  The const qualifies `()'; the type is a const function
returning...

|> As I read it, the first const modifies the int, and the second modifies
|> the p, regardless of whether the const is before or after the int or the p.
|> Nothing (really) modifies the *, which is the cause of all the confusion
|> since 'int const const p' would obviously be redundant.

Have you considered reading the draft standard?  Or the C standard?

In the declarations above, you have a constant pointer to a constant
int.  The int is declared with `int', and the pointer with `*'.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/06/06
Raw View
Sam Fenster (fenster@shadow.cs.columbia.edu) wrote:
|> kanze@gabi-soft.fr (J. Kanze) writes:
|> > Ron Hunsinger (hnsngr@sirius.com) wrote:
|> >>   char * const p, * q;
|> >> p is const, q is not. But what about
|> >>   char const *p, *q;
|> >> p points to const char. What does q point to? char, or const char?

|> > const char.

|> Pretty ugly and unintuitive, right?  All of a sudden, `const' is glued to
|> `char' (the type specifier) instead of to `*p' (the first declarator), when it
|> could still meaningfully be part of the declarator.  A badly-designed piece of
|> the C/C++ grammar.

According to the C/C++ grammar, `const' cannot meaningfully be part of
the declarator here.  As part of a declarator, the const always modifies
what it follows, *in* *the* *declarator*.  Thus, it is not meaningful
for it to be the first token in a declarator.

If your point is simply that the C/C++ grammar for declarations is not
particularly well-designed, you'll get no disagreement from me:-).
Given the way the grammar works (and worked, before const), I don't
really see any other way which const could fit in, however.

|> >>   const char *p, *q;
|> >> Is this any different? p still points to const char, but what does q
|> >> point to? Surely also const char, no?

|> > Yes.

|> In this case, when it comes before the type specifier `char', it's clear that
|> `const' must apply to both declarators.  It makes sense that it's parsed as
|> part of the specifier here.

|> Did you know that
|>    char *p, const *q;
|> is illegal?  Stupid grammar.  As part of a declarator, `const' must follow a
|> `*'.  And yet, `const *q' would make perfect sense.

|> > In the first case, the `const' is part of the declarator, and so only
|> > applies within the declarator.  In the two other cases, the `const' is part
|> > of the declaration specifier, and not of a declarator.  The declaration
|> > specifier applies to all of the declarators.

|> > IMHO, putting two (or more) declarators in a single declaration is just
|> > complicating something that is already complicated enough as is.

|> I disagree.  It's compact and convenient, and would be perfectly
|> understandable and without pitfalls if not for this particular design flaw.

|> I think a grammar that was in line with everyone's intuition would allow
|> `const' wherever `*' is allowed in a declarator, or before a type name in a
|> specifier.

I think I see what you are getting at.  You would like for `const' to be
a modifier, much like `*', rather than a qualifier.  Done
consequentially, this wouldn't allow `const' at all in the specifier
(since no modifiers are allowed in the specifier), thus banning:

 const int i ;

In addition, it would probably make it awkward for C++'s `const'
defaults to static linkage rule (since the storage class is part of the
specifier).
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
                             --Beratung in industrieller Datenverarbeitung





Author: shepherd@debussy.sbi.com (Marc Shepherd)
Date: 1995/06/06
Raw View
In article ft6@natasha.rmii.com, mike@if.com (MIke Homyack - System Owner) writes:
>
>Here's how I understand things to be.  'const' modifies the very next thing on
>the line.  So...
>
> const int *p; -- specifies a pointer to a constant integer (ie. you can change
>        where the pointer points, but you cannot use it to change
>        the value at that location)

Correct so far.

>
>  int const *p; -- specifies a constant pointer to an integer (ie. you can
>        use the pointer to change the value being pointed at, but
>        the pointer cannot point to another location in memory)

Bzzt.  Incorrect.  'int const *p' and 'const int *p' mean EXACTLY THE SAME THING
(see above).  Both mean that the pointer may vary, but the integer it points to
may not.

>
>And, lastly...
>
> const int const *p; -- specifies a constant pointer to a constant integer.
>          (ie. neither the value pointed at, nor the location
>          pointed to by the pointer may be changed)

Bzzt.  Incorrect.  'const int const *p' is redundant--both 'consts' constrain
the integer, not the pointer.  The syntax meeting your description is:
'const int * const p' or 'int const * const p' -- take your pick.

>
>Is my reading correct?...
>

Nope.

---
Marc Shepherd
Salomon Brothers Inc
shepherd@schubert.sbi.com The opinions I express are no one's but mine!






Author: peter@chinook.physics.utoronto.ca (Peter Berdeklis)
Date: 1995/06/06
Raw View
According to Marc Shepherd <shepherd@debussy.sbi.com>:
>'const int const *p' is redundant--both 'consts' constrain
> the integer, not the pointer.  The syntax meeting your description is:
> 'const int * const p' or 'int const * const p' -- take your pick.
   ^^^^^^^^^^^^^^^^^^^      ^^^^^^^^^^^^^^^^^^^

Is 'int const * p const' correct, and does it mean the same as the ex.'s
underlined above?

As I read it, the first const modifies the int, and the second modifies
the p, regardless of whether the const is before or after the int or the p.
Nothing (really) modifies the *, which is the cause of all the confusion
since 'int const const p' would obviously be redundant.

Is this correct?


Pete






Author: hnsngr@sirius.com (Ron Hunsinger)
Date: 1995/06/03
Raw View
In article <3qmqfr$2b9@gabi.gabi-soft.fr>, kanze@gabi-soft.fr (J. Kanze) wrote:

> Yes.  In the first case, the `const' is part of the declarator, and so
> only applies within the declarator.  In the two other cases, the `const'
> is part of the declaration specifier, and not of a declarator.  The
> declaration specifier applies to all of the declarators.

Thanks. I checked the grammar summary (which I should have done before
posting, but I succumbed to laziness. Sorry. Won't happen again) and see
that 'const' can be either a <type specifier> or a <cv-qualifier>, and
their uses are quite distinct.

I was thinking that const could be put just about anywhere, so something
like

   int p, const q;

would be permitted (it's not), and that made me think that

   int const p, q;

would be ambiguous (it isn't). And even if it were, you couldn't clarify it
(as I had thought) with something like

   int (const p), q;   // (also illegal).

> IMHO, putting two (or more) declarators in a single declaration is just
> complicating something that is already complicated enough as is.

I see nothing wrong with

   int i, j, k1, k2;

but that's an argument for another day. I want to know what things mean,
whether I intend to write them or not. (Sometimes I'm looking at someone
else's code. I'd rather be able to say "Ah hah! What you wrote means
thus-and-so!" rather than "Gee, I dunno, let's waste 15 minutes on another
compile just to see if this is your problem." I've had to fix up enough
code written by people who use the latter approach.)

-Ron Hunsinger





Author: thp@cs.ucr.edu (Tom Payne)
Date: 1995/06/03
Raw View
Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
: kanze@gabi-soft.fr (J. Kanze) writes:

: >|>  const int * p  // pointer to a const int
: >
: >Think about it awhile.  I think you'll realize that a `pointer to a const
: >int' and a `pointer to an int which is const' describe exactly the same
: >thing.

: The difference is that `pointer to a const int' is as far as I can tell
: unambiguous, whereas `pointer to an int which is const' could mean either
: `pointer to an (int which is const)', or `(pointer to an int) which is const'.
: If you mix prefix and postfix operators, you can get ambiguities which
: require precedence rules to resolve, but if you stick with unary prefix
: operators, there can be no ambiguity.


... provided that you hyphenate correctly:

   constant integer pointer      // "constant" modifies "integer pointer".

vs.

   constant-integer pointer     //  "constant-integer" modfifies "pointer".


Tom Payne





Author: glover@hikimi.cray.com (Roger Glover)
Date: 1995/06/03
Raw View
In article <KANZE.95Jun1122843@slsvhdt.lts.sel.alcatel.de>, kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:
> In article <3qhsaj$i43@watnews2.watson.ibm.com> jjb@watson.ibm.com
> (John Barton) writes:

[some stuff omitted]

> |> C++ declarations just don't read from left to right; neither do
> |> expressions:
> |>    x = (*fp)(y);  // assignment happens after the function evaluation.
>
> Correct.  And the only solution I've found so far is to consider the
> declaration a type expression, and parse it like an expression, with
> full respect for precedence and binding.
>
> Oh well, if it were easy, it wouldn't be C++:-).

So, if I may summarize, parsing declarations is like parsing
executable expressions *in reverse*.  In parsing an executable
expression you:
 - start with the identifier
 - work your way out of the expression
   -- in order of precedence
   -- with parenthetical subexpressions evaluated first

In parsing a declaration, you:
 - start outside the expression
 - work your way in to the identifier (peeling off the
   operators like onion skin)
   -- in *reverse* order of precedence
   -- with parenthetical subexpressions evaluated *last*

There are some examples below.

----------------------------------------------- Roger Glover
XXXX\ \ / \ /XXX  \ / \ X   \ /\\\  X///X /\\\  Cray Research, Inc.
/ \ / \/ /\ / \ / \X /\ X  \  / \   X\  \ X     DISCLAIMER HAIKU:
//X/  X\\\X //X/  X \ X X\\   / \   X/X \ X \\\   C R I may not
/ \   X///X / \/  X//XX X  \  / \   X  \\ X   \   Share these opinions with me
/ \   X   X /\\\/ X   X X///X /XXX/ X///X /XXX/   This is not my fault
-----------------------------------------------

Examples:

    int *fp();

 - "*fp()" is an int, so
 - "fp()" is a pointer to int, so
 - "fp" is a function returning pointer to int

    int (*fp)();

 - "(*fp)()" is an int, so
 - "(*fp)" is a function returning int, so
 - "fp" is a pointer to a function returning int

    int *fp[5];

 - "*fp[5]" is an int, so
 - "fp[5]" is a pointer to int, so
 - "fp" is an array of 5 pointers to int

    int (*fp)[3][5];

 - "(*fp)[3][5]" is an int, so
 - "(*fp)[3]" is an array of 5 ints, so
 - "*fp" is an array of 3 arrays of 5 ints, so
 - "fp" is a pointer to an array of 3 arrays of 5 ints

Now with const:

    const int **pp;

 - "**pp" is a constant int, so
 - "*pp" is a pointer to constant int, so
 - "pp" is a pointer to pointer to constant int

    int * const *pp;

 - "* const *pp" is an int, so
 - "*pp" is a constant pointer to an int, so
 - "pp" is a pointer to a constant pointer to an int

    int ** const pp;

 - "** const pp" is an int, so
 - "* const pp" is a pointer to an int, so
 - "pp" is a constant pointer to a pointer to an int





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/06/03
Raw View
kanze@gabi-soft.fr (J. Kanze) writes:

>|>  const int * p  // pointer to a const int
>
>Think about it awhile.  I think you'll realize that a `pointer to a const
>int' and a `pointer to an int which is const' describe exactly the same
>thing.

The difference is that `pointer to a const int' is as far as I can tell
unambiguous, whereas `pointer to an int which is const' could mean either
`pointer to an (int which is const)', or `(pointer to an int) which is const'.
If you mix prefix and postfix operators, you can get ambiguities which
require precedence rules to resolve, but if you stick with unary prefix
operators, there can be no ambiguity.

--
Fergus Henderson
fjh@cs.mu.oz.au
http://www.cs.mu.oz.au/~fjh





Author: fenster@shadow.cs.columbia.edu (Sam Fenster)
Date: 1995/06/02
Raw View
kanze@gabi-soft.fr (J. Kanze) writes:
> Ron Hunsinger (hnsngr@sirius.com) wrote:
>>   char * const p, * q;
>> p is const, q is not. But what about
>>   char const *p, *q;
>> p points to const char. What does q point to? char, or const char?

> const char.

Pretty ugly and unintuitive, right?  All of a sudden, `const' is glued to
`char' (the type specifier) instead of to `*p' (the first declarator), when it
could still meaningfully be part of the declarator.  A badly-designed piece of
the C/C++ grammar.

>>   const char *p, *q;
>> Is this any different? p still points to const char, but what does q
>> point to? Surely also const char, no?

> Yes.

In this case, when it comes before the type specifier `char', it's clear that
`const' must apply to both declarators.  It makes sense that it's parsed as
part of the specifier here.

Did you know that
   char *p, const *q;
is illegal?  Stupid grammar.  As part of a declarator, `const' must follow a
`*'.  And yet, `const *q' would make perfect sense.

> In the first case, the `const' is part of the declarator, and so only
> applies within the declarator.  In the two other cases, the `const' is part
> of the declaration specifier, and not of a declarator.  The declaration
> specifier applies to all of the declarators.

> IMHO, putting two (or more) declarators in a single declaration is just
> complicating something that is already complicated enough as is.

I disagree.  It's compact and convenient, and would be perfectly
understandable and without pitfalls if not for this particular design flaw.

I think a grammar that was in line with everyone's intuition would allow
`const' wherever `*' is allowed in a declarator, or before a type name in a
specifier.





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/06/02
Raw View
Ron Hunsinger (hnsngr@sirius.com) wrote:
|> Ok, related question:

|>   char * const p, * q;

|> p is const, q is not. But what about

|>   char const *p, *q;

|> p points to const char. What does q point to? char, or const char?

const char.

|>   const char *p, *q;

|> Is this any different? p still points to const char, but what does q
|> point to? Surely also const char, no?

Yes.  In the first case, the `const' is part of the declarator, and so
only applies within the declarator.  In the two other cases, the `const'
is part of the declaration specifier, and not of a declarator.  The
declaration specifier applies to all of the declarators.

IMHO, putting two (or more) declarators in a single declaration is just
complicating something that is already complicated enough as is.
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
                             --Beratung in industrieller Datenverarbeitung





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/06/02
Raw View
Mark Elston (elston@cave.arc.nasa.gov) wrote:
|> In article <3qhsaj$i43@watnews2.watson.ibm.com> jjb@watson.ibm.com (John Barton) writes:

|> >   Are there examples in which the "reading backwards" rule does not work?
|> > Here are the recently discussed example read backwards:
|> >    const int* p;  // a pointer to an int which is const
|> >    int const *p;  // a pointer to a const int
|> >    const int const *p; // a pointer to a const int which is const (error)
|> >    int *const p;       // a const pointer to an int
|> >    const int* const p; // a const pointer to an int which is const

|> I have never seen examples of the 2nd form.  Is this legal?

Yes.  I use it all of the time.  If you follow this group awhile, you'll
probably see examples.

|> the ARM
|> (8.2.1) has examples of the 1st and 4th forms and Scott Meyers
|> "Effective C++" (section 21) has examples of the 1st, 4th and 5th
|> forms.  I have never read of putting the const type spefifier between
|> the type name and the '*' or variable name.

Neither the ARM nor Scott Meyers could possibly have examples of *all*
legal C++ constructs.

|> And, pardon my dullness, but I don't understand what you're referring
|> to with your comments.

|>  const int * p  // pointer to a const int

Think about it awhile.  I think you'll realize that a `pointer to a const
int' and a `pointer to an int which is const' describe exactly the same
thing.  John was just trying to formulate a `reading backwards' rule,
which controled which form he used.

|>  int * const p  // const pointer to non-const int
|>  const int * const p // const pointer to const int

Delete the word `non-const' (as being implied), and this is exactly what
John wrote.

|> This is from both the ARM and "Effective C++".  Perhaps I am just
|> confused by your 2nd and 3rd forms, above.

Probably.  The standards committee felt that the 3rd form was confusing
enough to ban it.
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
                             --Beratung in industrieller Datenverarbeitung





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/01
Raw View
In article <3qhsaj$i43@watnews2.watson.ibm.com> jjb@watson.ibm.com
(John Barton) writes:

|> (I won't quote the preceeding articles in this thread since some
|> were confusing...)

|>   Are there examples in which the "reading backwards" rule does not work?

An obvious exception: in the presence of parentheses.

Are you concerned only about const, or do you want to consider the
type completely.  In the latter case, multiple dimensioned arrays
don't work either.

|> Here are the recently discussed example read backwards:
|>    const int* p;  // a pointer to an int which is const
|>    int const *p;  // a pointer to a const int

Since another poster apparently missed the fact: both of the above
descriptions actually say the same thing.

|>    const int const *p; // a pointer to a const int which is const (error)
|>    int *const p;       // a const pointer to an int
|>    const int* const p; // a const pointer to an int which is const
|> Actually, the reading backwards rule should be called a reading inside
|> out rule: start with the name being declared and then figure out what
|> it is.  So for functions:
|>    typedef X const * (*fp)(Y const * const);  // A pointer to a function
|>         // taking a const pointer to a const Y and returning a pointer
|>         // to a const X.

How exactly do you define the reading inside out rule.  If you mean
spiralling out one element at a time, it also fails with multiple
dimensions and pointers, e.g.:

 int * * a [5] [3] ;

This is an array[5] of an array[3] of pointers to pointers to int.
You read left to right after the name being declared, and left to
right before, always respecting parentheses.

Except that a final const in a function declaration refers to what is
to its left (the function).

And of course, another general problem is finding out just where what
is being declared would go when it is not present (for example, in a
new expression).

|> C++ declarations just don't read from left to right; neither do
|> expressions:
|>    x = (*fp)(y);  // assignment happens after the function evaluation.

Correct.  And the only solution I've found so far is to consider the
declaration a type expression, and parse it like an expression, with
full respect for precedence and binding.

Oh well, if it were easy, it wouldn't be C++:-).
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: hnsngr@sirius.com (Ron Hunsinger)
Date: 1995/06/01
Raw View
Ok, related question:

  char * const p, * q;

p is const, q is not. But what about

  char const *p, *q;

p points to const char. What does q point to? char, or const char?

  const char *p, *q;

Is this any different? p still points to const char, but what does q
point to? Surely also const char, no?

-Ron Hunsinger





Author: elston@cave.arc.nasa.gov (Mark Elston)
Date: 1995/06/01
Raw View
In article <3qhsaj$i43@watnews2.watson.ibm.com> jjb@watson.ibm.com (John Barton) writes:

>   Are there examples in which the "reading backwards" rule does not work?
> Here are the recently discussed example read backwards:
>    const int* p;  // a pointer to an int which is const
>    int const *p;  // a pointer to a const int
>    const int const *p; // a pointer to a const int which is const (error)
>    int *const p;       // a const pointer to an int
>    const int* const p; // a const pointer to an int which is const

I have never seen examples of the 2nd form.  Is this legal? the ARM
(8.2.1) has examples of the 1st and 4th forms and Scott Meyers
"Effective C++" (section 21) has examples of the 1st, 4th and 5th
forms.  I have never read of putting the const type spefifier between
the type name and the '*' or variable name.

And, pardon my dullness, but I don't understand what you're referring
to with your comments.

 const int * p  // pointer to a const int
 int * const p  // const pointer to non-const int
 const int * const p // const pointer to const int

This is from both the ARM and "Effective C++".  Perhaps I am just
confused by your 2nd and 3rd forms, above.

Mark.


--
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Mark Elston                       #include <std-disclaimer.h>
elston@cave.arc.nasa.gov          #include <std-witticism.h>






Author: poor@esu6.auckland.ac.nz (Edouard Poor)
Date: 1995/05/31
Raw View
kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:

>In article <3qe05m$hg4@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM
>(Steve Clamage) writes:

>|> jhalpin@netcom.com (Joe Halpin) writes:

>|>  const int *p;
>|>  int const *p;

>|> In both cases, you could say that "const" applies to the type (int),
>|> which is on the left or on the right in these equivalent declarations.
>|> In both declarations, the declarator is the "*"; it is exactly correct
>|> to say that the "const" modifies the declarator which immediately follows.

>Now you've got me confused.  The above paragraph seems almost
>contradictory; does the const modify (apply to) the int, or to the *
>(pointer).  (It better be the int, or all of my compilers are as
>broken as my understanding of the question.)

>The way I've always understood the above (and I think this corresponds
>to the draft) is that the const above is part of the declaration
>specification, and has nothing to do with the declarator.  Since the
>declaration specification is an unordered list, whether const preceeds
>or follows any other element in the list is irrelevant.  You can even
>write:

> unsigned const int   *p ;

>In this case, I guess you could say that const modifies what surrounds
>it:-).  (It is the unsigned int that is const.)

>(Whether the above is good style or not is another question.)

Kind of reminds me of the time I was having a bit of trouble understanding
the const rules in C (mainly through not bothering to read the relevant
sections carefully enough I guess)

I ended up deciding to convey the constness of my parameters by going
overboard:

  void function( const const const char const const * const const bob )

I must say I was a tiny bit shaken when my compiler didn't utter a
word about it during the next compile...

I must go home and see if I can find whether this is legal in the C++
draft. Should be enough to raise a dry smile in some code one day if
it is at least :-)

Edouard.





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/05/31
Raw View
In article <3qgm1q$e1b@net.auckland.ac.nz> poor@esu6.auckland.ac.nz
(Edouard Poor) writes:

|> Kind of reminds me of the time I was having a bit of trouble understanding
|> the const rules in C (mainly through not bothering to read the relevant
|> sections carefully enough I guess)

|> I ended up deciding to convey the constness of my parameters by going
|> overboard:

|>   void function( const const const char const const * const const bob )

|> I must say I was a tiny bit shaken when my compiler didn't utter a
|> word about it during the next compile...

|> I must go home and see if I can find whether this is legal in the C++
|> draft. Should be enough to raise a dry smile in some code one day if
|> it is at least :-)

I don't have a copy of the ARM nor the C standard handy to verify, but
I believe that neither of them contains any rule to forbid this.

The C++ draft does forbid this, explicitly.  See section 7.1.5.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: jjb@watson.ibm.com (John Barton)
Date: 1995/05/31
Raw View
(I won't quote the preceeding articles in this thread since some
were confusing...)

  Are there examples in which the "reading backwards" rule does not work?
Here are the recently discussed example read backwards:
   const int* p;  // a pointer to an int which is const
   int const *p;  // a pointer to a const int
   const int const *p; // a pointer to a const int which is const (error)
   int *const p;       // a const pointer to an int
   const int* const p; // a const pointer to an int which is const
Actually, the reading backwards rule should be called a reading inside
out rule: start with the name being declared and then figure out what
it is.  So for functions:
   typedef X const * (*fp)(Y const * const);  // A pointer to a function
        // taking a const pointer to a const Y and returning a pointer
        // to a const X.

C++ declarations just don't read from left to right; neither do
expressions:
   x = (*fp)(y);  // assignment happens after the function evaluation.

--
John.

John J. Barton        jjb@watson.ibm.com            (914)784-6645
 <http://www.research.ibm.com/xw-SoftwareTechnology>
H1-C13 IBM Watson Research Center P.O. Box 704 Hawthorne NY 10598





Author: ajw@ornews.intel.com (Alan Waldock)
Date: 1995/05/31
Raw View
In article <KANZE.95May31123505@slsvhdt.lts.sel.alcatel.de>,
James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de> wrote:
>In article <3qgm1q$e1b@net.auckland.ac.nz> poor@esu6.auckland.ac.nz
>(Edouard Poor) writes:


|>   void function( const const const char const const * const const bob )

|> I must say I was a tiny bit shaken when my compiler didn't utter a
|> word about it during the next compile...

>The C++ draft does forbid this, explicitly.  See section 7.1.5.

Pity. There go dreams of "#define spam const"...

-- Alan_Waldock@ccm.jf.intel.com
   From, but not on behalf of, Intel Corporation






Author: imp@village.org (Warner Losh)
Date: 1995/05/31
Raw View
In article <3qhsaj$i43@watnews2.watson.ibm.com>,
John Barton <jjb@watson.ibm.com> wrote:
>   const int* p;  // a pointer to an int which is const
>   int const *p;  // a pointer to a const int

These are exactly the same thing.  A pointer to an int whose value you
cannot change via this pointer.

Warner
--
Warner Losh  "VMS Forever"  home: imp@village.org
Cyberspace Development, Inc   work: imp@marketplace.com
Makers of TIA, The Internet Adapter.  http://marketplace.com/





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/05/30
Raw View
In article <3qe05m$hg4@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM
(Steve Clamage) writes:

|> jhalpin@netcom.com (Joe Halpin) writes:

|> >I thought I understood how 'const' is used in C++, but I'm questioning
|> >that now. Would someone here care to define whether 'const' preceeds
|> >or follows what it qualifies?

|> >The following quote from the ARM is where my understanding comes from:

|> >"When a const or volatile type specifier appears in a declaration, it
|> >modifies the immediately following declarator..." (section 8.2.1)

|> That quote is correct. The problem arises in defining "declarator".
|> If you understand "declarator", you won't have any problem
|> understanding how to use "const" in a declaration or how to read
|> a declaration that uses "const".

|> The problem is that "declarator" is a difficult concept, and doesn't
|> have a simple definition, due to the "inside-out" nature of C++
|> declaration syntax.

|> Thus you often find in articles on the net and in magazines a statement
|> like "const modifies the thing to the right" or "... the thing to the
|> left". Interestingly, both simplifications are partially correct, if
|> contradictory, depending on exactly how a declaration is written.

|>  const int *p;
|>  int const *p;

|> In both cases, you could say that "const" applies to the type (int),
|> which is on the left or on the right in these equivalent declarations.
|> In both declarations, the declarator is the "*"; it is exactly correct
|> to say that the "const" modifies the declarator which immediately follows.

Now you've got me confused.  The above paragraph seems almost
contradictory; does the const modify (apply to) the int, or to the *
(pointer).  (It better be the int, or all of my compilers are as
broken as my understanding of the question.)

The way I've always understood the above (and I think this corresponds
to the draft) is that the const above is part of the declaration
specification, and has nothing to do with the declarator.  Since the
declaration specification is an unordered list, whether const preceeds
or follows any other element in the list is irrelevant.  You can even
write:

 unsigned const int   *p ;

In this case, I guess you could say that const modifies what surrounds
it:-).  (It is the unsigned int that is const.)

(Whether the above is good style or not is another question.)

Within the declarator, of course, the rules are different.  (This is
C++, after all.  Can't make it too easy.)  Const always binds to the
declarator (pointer, function) which preceeds it.  See sections 8.3.1
and 8.3.5 in the draft.  (And note well when reading that these
sections *only* apply to the declarator.  For the declaration
specifier, see 7.1.)

BTW, the quote from the ARM seems to me to be in direct contradiction
to the C++ draft and the C standard.  So unlike Steve, I don't
consider it correct.

Also, I constantly hear about various schemes to simplify reading the
declarations: right to left, left to right, or most often, spiralling
out.  They all fail at some point.  There is no simple rule.  To
understand C++ declarations, you *have* to understand C++
declarations.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: jhalpin@netcom.com (Joe Halpin)
Date: 1995/05/30
Raw View
I thought I understood how 'const' is used in C++, but I'm questioning
that now. Would someone here care to define whether 'const' preceeds
or follows what it qualifies?

The following quote from the ARM is where my understanding comes from:

"When a const or volatile type specifier appears in a declaration, it
modifies the immediately following declarator..." (section 8.2.1)

Joe
--
Joe Halpin
jhalpin@netcom.com
---------------------------------------------------------------------------





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/05/30
Raw View
jhalpin@netcom.com (Joe Halpin) writes:

>I thought I understood how 'const' is used in C++, but I'm questioning
>that now. Would someone here care to define whether 'const' preceeds
>or follows what it qualifies?

>The following quote from the ARM is where my understanding comes from:

>"When a const or volatile type specifier appears in a declaration, it
>modifies the immediately following declarator..." (section 8.2.1)

That quote is correct. The problem arises in defining "declarator".
If you understand "declarator", you won't have any problem
understanding how to use "const" in a declaration or how to read
a declaration that uses "const".

The problem is that "declarator" is a difficult concept, and doesn't
have a simple definition, due to the "inside-out" nature of C++
declaration syntax.

Thus you often find in articles on the net and in magazines a statement
like "const modifies the thing to the right" or "... the thing to the
left". Interestingly, both simplifications are partially correct, if
contradictory, depending on exactly how a declaration is written.

 const int *p;
 int const *p;

In both cases, you could say that "const" applies to the type (int),
which is on the left or on the right in these equivalent declarations.
In both declarations, the declarator is the "*"; it is exactly correct
to say that the "const" modifies the declarator which immediately follows.

--
Steve Clamage, stephen.clamage@eng.sun.com





Author: mike@if.com (MIke Homyack - System Owner)
Date: 1995/05/30
Raw View
On 30 May 1995 08:38:27 GMT, James Kanze US/ESC 60/3/141 #40763 (kanze@lts.sel.alcatel.de) wrote:
 - In article <3qe05m$hg4@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM
 - (Steve Clamage) writes:

 - |> jhalpin@netcom.com (Joe Halpin) writes:

 - |> >I thought I understood how 'const' is used in C++, but I'm questioning
 - |> >that now. Would someone here care to define whether 'const' preceeds
 - |> >or follows what it qualifies?

 [snip]

 - |>  const int *p;
 - |>  int const *p;

 [snip]

 - --
 - James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
 - GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
 - Conseils en informatique industrielle --
 -                               -- Beratung in industrieller Datenverarbeitung


Here's how I understand things to be.  'const' modifies the very next thing on
the line.  So...

 const int *p; -- specifies a pointer to a constant integer (ie. you can
        where the pointer points, but you cannot use it to change
        the value at that location)

  int const *p; -- specifies a constant pointer to an integer (ie. you can
        use the pointer to change the value being pointed at, but
        the pointer cannot point to another location in memory)

And, lastly...

 const int const *p; -- specifies a constant pointer to a constant integer.
          (ie. neither the value pointed at, nor the location
          pointed to by the pointer may be changed)

Is my reading correct?...

--
== === =    == === =============================================================
==  =  = === = === ==  Mr.H (mike@mrhappy.if.com)                             ==
== = = =    ==     ==  All opinions expressed herein are mine alone... right? ==
== === = === = === ==  "Goodbye boys!" ... "Have fun storming the castle!"    ==
== === = === = === =============================================================
All mail accepted...   Encrypted mail preferred...   E-Mail me for my public key
PGP fingerprint:  CC BD FD 38 BD C2 FB 56  02 AA 3C 7A 68 BB AF 54





Author: bkline@cortex.nlm.nih.gov (Bob Kline Phoenix Contract)
Date: 1995/05/30
Raw View
MIke Homyack - System Owner (mike@if.com) wrote:
: Here's how I understand things to be.  'const' modifies the very next
: thing on the line.  So...

Have you talked with your compiler about this understanding recently? :->}
Seriously, though, that's not how it works.

const int *ip;
    and
int const *ip;

mean the same thing: you can change the value of ip, but not *ip.

int i;
int * const ip = &i;

means you can change *ip but not ip.  It is confusing, but the
likelihood the language would be modified to eliminate some of
the confusion is very, very close to 0, so how about followups
to comp.lang.c++?

--
/*----------------------------------------------------------------------*/
/* Bob Kline                                       Stream International */
/* bob_kline@stream.com               formerly Corporate Software, Inc. */
/* voice: (703) 522-0820 x-311                      fax: (703) 522-5407 */
/*----------------------------------------------------------------------*/





Author: pstemari@erinet.com (Paul J. Ste. Marie)
Date: 1995/05/30
Raw View
In article <3qfch3$ft6@natasha.rmii.com>,
   mike@if.com (MIke Homyack - System Owner) wrote:
 [snip]
:Here's how I understand things to be.  'const' modifies the very
:next thing on the line.  So...
:
: const int *p; -- specifies a pointer to a constant integer
:                        (ie. you can [change?] where the pointer
:                         points, but you cannot use it to change
:                         the value at that location)

That's right.

:  int const *p; -- specifies a constant pointer to an integer
:                        (ie. you can use the pointer to change the
:                         value being pointed at, but the pointer
:                         cannot point to another location in
:                         memory)

Wrong.  This is the same as above.  What you what here is
 int * const p;
ie--const modifies the declarator to the right.  * means "pointer
to", const * means "pointer to const", and both int const * and
const int * mean "pointer to const int".

:And, lastly...
:
: const int const *p; -- specifies a constant pointer to a :
                             constant integer.

Compiler error, I'd hope.  This should be "const int * const p"--
the first const modifies the *, and the second modifies the p.

 --Paul J. Ste. Marie, pstemari@well.sf.ca.us, pstemari@erinet.com

The Financial Crimes Enforcement Network claims that they capture every
public posting that has their name ("FinCEN") in it.  I wish them good hunting.





Author: rad6938@gemini.tntech.edu (Rad)
Date: 1995/05/30
Raw View
In article <3qfch3$ft6@natasha.rmii.com>, mike@if.com (MIke Homyack - System Owner) writes:
>On 30 May 1995 08:38:27 GMT, James Kanze US/ESC 60/3/141 #40763 (kanze@lts.sel.alcatel.de) wrote:
> - In article <3qe05m$hg4@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM
> - (Steve Clamage) writes:
>
> - |> jhalpin@netcom.com (Joe Halpin) writes:
>
> - |> >I thought I understood how 'const' is used in C++, but I'm questioning
> - |> >that now. Would someone here care to define whether 'const' preceeds
> - |> >or follows what it qualifies?
>
> [snip]
>
> - |>  const int *p;
> - |>  int const *p;
>
>Here's how I understand things to be.  'const' modifies the very next thing on
>the line.  So...
> const int *p; -- specifies a pointer to a constant integer (ie. you can
>        where the pointer points, but you cannot use it to change
>        the value at that location)
>  int const *p; -- specifies a constant pointer to an integer (ie. you can
>        use the pointer to change the value being pointed at, but
>        the pointer cannot point to another location in memory)
>And, lastly...
> const int const *p; -- specifies a constant pointer to a constant integer.
>          (ie. neither the value pointed at, nor the location
>          pointed to by the pointer may be changed)
>Is my reading correct?...

No, this is not correct.
   "const int *p;" and "int const *p;" both declare pointers to integer
constants.  The order of the declaration specifiers (storage class specifier,
type specifier, and cv-qualifiers) does not matter.  In order to declare a
constant pointer you need the cv-qualifier in the pointer declarator
"int * const p;"

----------------------------------------------------------------------------
 Richard Deken                   Graduate student in electrical engineering
 PGP public key available      Tennessee Technological University
 Internet: rad6938@gemini.tntech.edu        Cookeville, TN, USA