Topic: const int& or int const&


Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/02/10
Raw View
John Lacey <johnl@vizdom.com> writes:

>David R Tribble wrote:
>>
>> There seems to be a minority of programmers who insist on
>> placing the 'const' specifier of a type after the type, such
>> as 'int const' instead of 'const int'.  Personally I abhor this
>> style; it's just another way to confuse people and is a break from
>> well-accepted practice that's been around for several years now.

>The entire declaration syntax is regrettable and confusing.

Yes. It is inherited from C, and given the goals of C++, could
not reasonably be changed. Too bad, because the syntax is
not only difficult for people to read and write, but is
difficult for compilers to parse. (The declaration syntax is
not LR(k), for grammar afficionados.)

>The reason for the behavior of the minority, as I'm sure David
>knows, is that "const" is a postfix qualifier, except when it
>appears in the left-most position. I agree that the combination
>is a source of confusion, but I believe the left-most exception
>is the problem, not the solution.

Actually, it is neither a prefix nor a postfix modifier. It
is part of a "declaration-specifier". A declaration-specifier
modifies the "declarator" which follows. (Except for the storage
class, which applies to the top-level declarator, not to any
intermediate declarator. Sigh.)

The point of confusion occurs when people try to simplify
the complicated syntax rules. The simplifications ("modifies what
comes before", "modifies what comes after", "look right then left",
"look inside out", etc) are not always correct and helpful.

A declaration-specifier may include storage class, type name,
and const or volatile qualifiers (and some things we'll ignore).
Example:
 extern const int foo;
The first three words are all part of one declaration-specifier,
and their order doesn't matter. Any of the six permutations of the
three words has the same meaning.  The declarator in this example
is "foo", and therefore represents a constant int object with
external linkage.

A pointer or reference operator is itself (part of) a declarator,
not a declaration-specifier.
Example:
 int const * volatile x;
Here, the first declaration-specifier is "int const", and modifes
the pointer. The next declaration-specifier is "volatile" and
modifies the declator x. So x is volatile, and is a pointer. It
points to a constant int.

If you just thought, "Aha! I just have to read right to left!",
you fell into a common trap. That rule doesn't work for function
declarations, among other things. But that's enough for now.

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

--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern/std-c++/faq.html                  ]





Author: John Lacey <johnl@vizdom.com>
Date: 1998/02/07
Raw View
David R Tribble wrote:
>
> There seems to be a minority of programmers who insist on
> placing the 'const' specifier of a type after the type, such
> as 'int const' instead of 'const int'.  Personally I abhor this
> style; it's just another way to confuse people and is a break from
> well-accepted practice that's been around for several years now.

The entire declaration syntax is regrettable and confusing.

The reason for the behavior of the minority, as I'm sure David
knows, is that "const" is a postfix qualifier, except when it
appears in the left-most position. I agree that the combination
is a source of confusion, but I believe the left-most exception
is the problem, not the solution.

It would be interesting to know why the left-most exception
exists at all. I suspect it is, as David suggested, the unnatural
feeling of postfix "const" together with the relative rarity of
constant pointers, e.g. "int * const". Now, of course, we also
have const member functions, where the postfix rule appears more
natural.

Two questions come to mind. Is there a good reason why "const" is
postfix rather than prefix? Also, does volatile behave the same
way, or does it behave like a storage-class specifier, despite
being listed in the grammar, along with const, as a
type-qualifier?

John L


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David R Tribble <dtribble@flash.net>
Date: 1998/02/09
Raw View
I, David R Tribble wrote:
> > There seems to be a minority of programmers who insist on
> > placing the 'const' specifier of a type after the type, such
> > as 'int const' instead of 'const int'.  Personally I abhor this
> > style; it's just another way to confuse people and is a break from
> > well-accepted practice that's been around for several years now.

John Lacey wrote:
> The entire declaration syntax is regrettable and confusing.
>
> The reason for the behavior of the minority, as I'm sure David
> knows, is that "const" is a postfix qualifier, except when it
> appears in the left-most position.

I can buy that.  But tradition is tradition, and we must also consider
what we teach beginning programmers.  I've always felt that too
many ways to state the same thing was a bad idea; you need to learn
two or more syntaxes for the same thing, but what have you gained
with this extra knowledge?   In many situations, two ways is one too
many.

> Two questions come to mind. Is there a good reason why "const" is
> postfix rather than prefix?

There had to be a way to specify constant pointers without breaking
the existing syntax for pointers to constant objects.  Hence, we have
'type *const' and 'const type *', respectively (and 'const type *const'
for cases of both).

> Also, does volatile behave the same
> way, or does it behave like a storage-class specifier, despite
> being listed in the grammar, along with const, as a
> type-qualifier?

'volatile' is syntactically identical to 'const'.  (In C9X, the new
qualifier 'restrict' acts this way, too.)  They share common ground
semantically, so it makes sense that they should be syntactically
similar.  But 'mutable' is a storage-class specifier like 'static'
[7.1.1], even though it arguably shares some semantics with 'const'.
Strange, no?

______________________________________________________________________
David R. Tribble
dtribble@technologist.com
dtribble@flash.net              http://www.flash.net/~dtribble/


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Bradd W. Szonye" <bradds@concentric.net>
Date: 1998/02/06
Raw View
Martin Neimeier wrote in message <34D8AD3C.5C38416B@heidelbg.ibm.com>...
>What is the difference between the three method-headers ?
>
>void foo(const in& foo_var);
>void foo(int const& foo_var);

These two are the same, and mean "reference to constant integer."

>void foo(const int const& foo_var);

This is ill-formed as written; redundant cv-qualifiers are not allowed
except as the by-product of a typedef or template instantiation. (The
cv-qualifiers, in case you are unfamiliar, are "const" and "volatile."
They are redundant in this example because both consts modify "int.")

The rule of thumb is that "const" modifies the syntactic element
immediately to its left. The major exception is that "const" written
left of the declared type modifies the element to its right (the type):

    brackets indicate const grouping
    [const int] *
    [int const] *
    [int const int] * // illegal
    [int const] [* const]

By the way, I prefer the "T const &" syntax myself; it works better with
text processing tools and is easier to explain than the full rule, which
has an exception.

Is this a FAQ? It seems to be a common question recently. I know I've
seen it in exactly this form before.

Bradd W. Szonye
bradds@concentric.net
http://www.concentric.net/~Bradds
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern/std-c++/faq.html                  ]





Author: "Tom McKearney" <no@spam.com>
Date: 1998/02/06
Raw View
Martin Neimeier wrote in message <34D8AD3C.5C38416B@heidelbg.ibm.com>...
>What is the difference between the three method-headers ?
>
>void foo(const in& foo_var);
>void foo(int const& foo_var);
>void foo(const int const& foo_var);

You can get this from the C++ FAQ, but here goes (hope I am thinking
clearly)...

1) void foo(const int& foo_var);

this is a function that takes a reference to a const int.  This means the
integer can't be modified.

2) void foo(int const& foo_var);

this is also a function that takes a reference to a const int.  This means
the integer can't be modified.

3) void foo(const int const& foo_var);

I am not sure if this is valid.  I am too lazy to look it up, but I think it
is invalid.

The difference between placement of const is easier to define with
pointers..

1) void foo(const int* foo_var)
2) void foo(int const* foo_var)

These would take a pointer to a const int.  The integer is not modifiable,
but the pointer can be modified (i.e. reseated).

3) void foo(int *const foo_var)

This takes a const pointer to an integer.  The integer can be modified, but
the pointer can be.

4) void foo(const int* const foo_var)

This takes a const pointer to a const integer.  Neither the integer, nor the
pointer may be modified.

I hope this helps.

Tom McKearney
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern/std-c++/faq.html                  ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/02/06
Raw View
Martin Neimeier <neimeier@heidelbg.ibm.com> wrote:
: What is the difference between the three method-headers ?

: void foo(const in& foo_var);
: void foo(int const& foo_var);
: void foo(const int const& foo_var);

The first two are identical, the third is illegal.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern/std-c++/faq.html                  ]





Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1998/02/06
Raw View
Martin Neimeier wrote:
> What is the difference between the three method-headers ?
>
> void foo(const in& foo_var);
> void foo(int const& foo_var);
> void foo(const int const& foo_var);

The placement of 'const' and 'int' are interchangeable (as long as
they come before the '&'), so your declarations are equivalent to
these:
    void foo(const int & var);          // 1
    void foo(const int & var);          // 2
    void foo(const const int & var);    // 3, bad

I've simply placed the 'const' before the 'int', since in these
cases they're equivalent.  (1) and (2) are the same.  (3) is
ill-formed because you've got more than one 'const' specifier.

There seems to be a minority of programmers who insist on
placing the 'const' specifier of a type after the type, such
as 'int const' instead of 'const int'.  Personally I abhor this
style; it's just another way to confuse people and is a break from
well-accepted practice that's been around for several years now.
Besides, it doesn't read as well; 'const int' sounds more natural
and descriptive of what it is (a "constant integer") than
'int const'.

In a related vein, these declarations are also equivalent to
each other:
    void bar(const int & foo);          // A
    void bar(const int &const foo);     // B

Both (A) and (B) declare 'foo' to be a reference to a const int.
(A) is well-formed.  (B) is legal, but the '&const' is meaningless;
it declares that 'foo' is a reference variable that can't be
modified; but references, by definition, can't be modified, so the
extra 'const' is redundant.

-- David R. Tribble, david.tribble@noSPAM.central.beasys.com --
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern/std-c++/faq.html                  ]





Author: Martin Neimeier <neimeier@heidelbg.ibm.com>
Date: 1998/02/04
Raw View
What is the difference between the three method-headers ?

void foo(const in& foo_var);
void foo(int const& foo_var);
void foo(const int const& foo_var);

thanks in advance
martin



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]