From: John H. on
Joseph M. Newcomer wrote:
> John H. wrote:
> >// In the foo.h:
> >void print_x(int num_times);
> >// In the foo.cpp:
> >#include "foo.h"
> >#include <iostream>
> >void print_x(int const num_times)
> ****
> This normally results in an error from the compiler because the forward reference in the
> header file conflicts with the definition. That would be 'const int' not 'int const'.

I know you know that they are the same, but just to clarify for
readers who might not, declaring a type as "int const" and "const int"
has the same semantic effect. It is really a matter of style. As
such, it is best to stick with whatever style is being used already in
the software project. For new projects, I prefer to put the const
after the int. This way when a coder is trying to determine what
exactly a "int setValues(Values const * const v) const { ... }" means,
they can use one rule: const refers to the thing that precedes it.
Historically, "const int" is the more commonly used style. However I
do see the "int const" style being used a little more, for instance
the C++ FAQ Lite section that talks about const recently switched from
"const int", to "int const" style. Readers interested in learning
more on this might check out http://www.parashift.com/c++-faq-lite/const-correctness.html
for more info.

> ****
> >{
> > for(int i=0; i<num_times; ++i)
> > {
> > std::cout << 'x';
> > }
> >}
> >
> >This is the idea I was trying to say when I said put const in the
> >definition but not the declaration.
> ****
> I knew that, and that's why I said it wouldn't work.
> ****
> >Here, from the caller's point of
> >view, it seems like an irrelevant detail on whether num_times is a
> >const parameter or not. The parameter is copied so whatever they
> >passed cannot be modified anyways. The function should produce the
> >same result either way. The fact that the implementation doesn't
> >modify num_times is really something only of interest to the
> >implementation. A implementation could in fact modify num_times and
> >still be correct, something like the following (untested):
> ****
> Which would be fine if that's the way the language and compilers worked, but that isn't
> how they work.

For the point I was trying to make, if I am understanding things
correctly, C++98, C++03 8.3.5/3 and C++0x draft 8.3.5/5 say that it is
legal: "Such cv-qualifiers affect only the definition of the parameter
within the body of the function; they do not affect the function
type." Also, VC++ 6, 2008 and 2010 RC seem work this way.
From: Doug Harrison [MVP] on
On Wed, 07 Apr 2010 22:43:40 -0400, Joseph M. Newcomer
<newcomer(a)flounder.com> wrote:

> John H. wrote:
>>I was trying to use pass-by-value to mean situations where the value
>>that is copied is not a reference or pointer. For references or
>>pointers I will call that pass-by-reference.

Pass-by-reference means one thing in C++, and that is to use a reference.
Actually, it would be more descriptive to use "receive by reference"
(function parameters) and "return by reference" (functions that return
references), but together, they constitute "pass by reference" in C++.
OTOH, pointers are objects, and they are no different than ints or any
other object in terms of how they are passed. I would not call using a
pointer parameter "pass by reference" because (a) It's not commonly called
that, even in C, for which it's the method to simulate pass by reference,
and (b) What do you call it when you use a reference to a pointer in C++,
e.g. "int*&"?.

>>> Since there is *only* pass-by-value in C and C++
>>> ("reference" or "pointer" are VALUES that are passed)
>No, officially, there is no such concept in C or C++. The "pointer" or "reference" (C++)
>is a concept that is implemented via pass-pointer-by-value.

This is sort of mixing implementation with the conceptual level. References
are not objects. A reference is just another name for the object bound to
it - That's the concept. Unlike pointers, references don't have sizes
(sizeof returns the size of the referent), their addresses cannot be taken,
and so forth. This is because conceptually, references are not objects, and
thus conceptually don't exist as regions of memory, which is the definition
of "object". Of course, references are normally implemented in terms of
pointers, but you can only ever observe that indirectly, like when a class
contains a reference member, objects of that class will typically be larger
by the size of a pointer, a pointer being used to represent the reference
under the hood. I can't think of any other place where the implementation
of references creeps into ordinary programming even in this indirect kind
of way.

--
Doug Harrison
Visual C++ MVP
From: Doug Harrison [MVP] on
On Thu, 8 Apr 2010 10:34:26 -0700 (PDT), "John H."
<oldman_fromthec(a)yahoo.com> wrote:

>For the point I was trying to make, if I am understanding things
>correctly, C++98, C++03 8.3.5/3 and C++0x draft 8.3.5/5 say that it is
>legal: "Such cv-qualifiers affect only the definition of the parameter
>within the body of the function; they do not affect the function
>type." Also, VC++ 6, 2008 and 2010 RC seem work this way.

It is true that these declare the same function:

void f(int);
void f(int const);

The const in the second one is a "top-level cv qualifier" and is thus
irrelevant to determining the function type (and thus overloading). This is
what allows you to use the former for interface purposes and the latter for
implementation purposes, which mitigates the "noise" complaint. Really, if
you use "const" inside the function body, it's strange not to use it for
parameters, but it's pretty much standard practice not to. Standards
shouldn't always be followed... :)

--
Doug Harrison
Visual C++ MVP