Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Why const int& ? (http://www.velocityreviews.com/forums/t805612-why-const-int-and.html)

Travis Parks 11-06-2011 05:00 PM

Why const int& ?
 
Could someone quickly remind me why functions taking ints should
consider passing by constant reference?

I know the constant part allows you to pass literals, but I am trying
to remember what benefit there is to using references instead of
relying on plain copy semantics.

Also, does:

const int&

mean:

int const&

or:

int &const

Finally, what would int const&const mean? Does it make sense to mark
an int as constant, considering by nature it already is? Is this
syntax legal?

Thanks,
Travis Parks

Marc 11-06-2011 05:12 PM

Re: Why const int& ?
 
Travis Parks wrote:

> Could someone quickly remind me why functions taking ints should
> consider passing by constant reference?


For fun? Because you are paid according to the size of the code?

> Also, does:
>
> const int&
>
> mean:
>
> int const&


Yes.

> or:
>
> int &const


Invalid. If you are thinking of the analogy with pointers, references
are always const.

> Finally, what would int const&const mean?


Nothing.

> Does it make sense to mark an int as constant, considering by nature it
> already is?


Read up on the difference between lvalue and rvalue.

Ian Collins 11-06-2011 06:43 PM

Re: Why const int& ?
 
On 11/ 7/11 06:00 AM, Travis Parks wrote:
> Could someone quickly remind me why functions taking ints should
> consider passing by constant reference?


Your wouldn't normally pass an int by const reference, but if you are
declaring a template, then const reference ( const T& ) is appropriate.

--
Ian Collins

Joshua Maurice 11-07-2011 10:36 PM

Re: Why const int& ?
 
On Nov 6, 9:00*am, Travis Parks <jehugalea...@gmail.com> wrote:
> Also, does:
>
> const int&
>
> mean:
>
> int const&
>
> or:
>
> int &const
>
> Finally, what would int const&const mean? Does it make sense to mark
> an int as constant, considering by nature it already is? Is this
> syntax legal?


int const & x -- a reference to const int
const int & x -- a reference to const int
int & const x -- ill formed code that should trigger a compiler error

int const * x -- a (non-const) pointer to const int
const int * x -- a (non-const) pointer to const int
int * const x -- a const pointer to (non-const) int

Travis Parks 11-08-2011 02:37 AM

Re: Why const int& ?
 
On Nov 7, 5:36*pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
> On Nov 6, 9:00*am, Travis Parks <jehugalea...@gmail.com> wrote:
>
> > Also, does:

>
> > const int&

>
> > mean:

>
> > int const&

>
> > or:

>
> > int &const

>
> > Finally, what would int const&const mean? Does it make sense to mark
> > an int as constant, considering by nature it already is? Is this
> > syntax legal?

>
> int const & x -- a reference to const int
> const int & x -- a reference to const int
> int & const x -- ill formed code that should trigger a compiler error
>
> int const * x -- a (non-const) pointer to const int
> const int * x -- a (non-const) pointer to const int
> int * const x -- a const pointer to (non-const) int


Ah. That clears some things up. A trailing const only makes sense in
terms of pointers, not references.

So, say you had a block of code that looked like this:

vector<int> values;
init(values);

void init(vector<int> & values)
{
vector<int> v;
values = v; // assignment operator
}

How can I tell the compiler a) that I don't want to change the vector
and b) that I don't want the vector to be reassigned?

My guess right now is you handle both a and b the same way, since the
assignment operator modifies the internals of the vector.

Working in languages like C# and Java, where everything is a reference
type, it is strange to think that an assignment modifies the contents
of the original vector (copying v), rather than simply refering both
to the same vector.

On the other hand, pointers work the same way as reference types in
Java and C#, hence the ability to add the extra const onto the end.

Let me know if I'm on the right trail.

Joshua Maurice 11-09-2011 01:13 AM

Re: Why const int& ?
 
On Nov 7, 6:37*pm, Travis Parks <jehugalea...@gmail.com> wrote:
> On Nov 7, 5:36*pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
>
>
>
>
>
>
>
>
>
> > On Nov 6, 9:00*am, Travis Parks <jehugalea...@gmail.com> wrote:

>
> > > Also, does:

>
> > > const int&

>
> > > mean:

>
> > > int const&

>
> > > or:

>
> > > int &const

>
> > > Finally, what would int const&const mean? Does it make sense to mark
> > > an int as constant, considering by nature it already is? Is this
> > > syntax legal?

>
> > int const & x -- a reference to const int
> > const int & x -- a reference to const int
> > int & const x -- ill formed code that should trigger a compiler error

>
> > int const * x -- a (non-const) pointer to const int
> > const int * x -- a (non-const) pointer to const int
> > int * const x -- a const pointer to (non-const) int

>
> Ah. That clears some things up. A trailing const only makes sense in
> terms of pointers, not references.
>
> So, say you had a block of code that looked like this:
>
> vector<int> values;
> init(values);
>
> void init(vector<int> & values)
> {
> * * vector<int> v;
> * * values = v; // assignment operator
>
> }
>
> How can I tell the compiler a) that I don't want to change the vector
> and b) that I don't want the vector to be reassigned?
>
> My guess right now is you handle both a and b the same way, since the
> assignment operator modifies the internals of the vector.
>
> Working in languages like C# and Java, where everything is a reference
> type, it is strange to think that an assignment modifies the contents
> of the original vector (copying v), rather than simply refering both
> to the same vector.
>
> On the other hand, pointers work the same way as reference types in
> Java and C#, hence the ability to add the extra const onto the end.
>
> Let me know if I'm on the right trail.


Sort of. Unfortunately, AFAIK, Java developers decided that "pointer"
was a dirty word and used the word "reference" instead. Java
references really ought to have been called pointers. Java references
have more or less the same semantics as C++ pointers (except of course
no pointer arithmetic, etc.). That is, a C++ pointer is a "region of
memory" distinct from the "region of memory" of the pointed-to thingy.
Same as Java. In C++ parlance, the pointer is an object, and it points
to a separate object.
int x; // an object
int* y = & x; // the pointer object y points to the int object x

A C++ reference is not a distinct object. It is merely another name
for a pre-existing object. Now, as an implementation detail, it's
probably implemented as a pointer, but that's an implementation
detail. You cannot make a const reference (contrast with "reference to
const"). All references are implicitly "const" - all references are
unchangeable. You cannot "reseat" a reference. Once a C++ reference is
created, it "points" to the same object for the reference's lifetime.
Any attempt to reseat the reference invokes undefined behavior (more
or less - IIRC there might be an obscure exception or two - ignore
that for now).

So, for:
void foo(vector<int> * x)
The body of the function can reassign x to point to a different vector
object. The caller's pointer remains unchanged no matter what.
However, the pointed-to object may be changed, and this is visible to
the caller. That is, pointer have "pass by value" semantics, just like
Java references. A change to the C++ pointer object in the body does
not affect the caller, but a change to the pointed-to object does
affect the caller.

void foo(vector<int> & x)
The body of the function cannot reassign x to "point" to a different
vector object. Any attempt to do so is undefined behavior (more or
less - IIRC there might be an obscure exception or two - ignore that
for now). "x" is just another name for an already existing vector
object. Any changes to x will affect the caller.

void foo(vector<int> const * x)
The caller knows that the function body won't modify the vector object
(more or less - const_casts can, and you might be able to obtain a non-
const reference to it through some other means and modify it through
that).

void foo(vector<int> * const x)
The caller doesn't care about this const. This const only affects the
body's local pointer object which the caller does not see.

void foo(vector<int> const & x)
The caller knows that the function body won't modify the vector object
(more or less - const_casts can, and you might be able to obtain a non-
const reference to it through some other means and modify it through
that).

void foo(vector<int> & const x)
Ill-formed code. References are not distinct objects from the "pointed
to" object. They are simply another name for an existing object. The
const there doesn't mean anything.

Juha Nieminen 11-09-2011 09:00 AM

Re: Why const int& ?
 
Joshua Maurice <joshuamaurice@gmail.com> wrote:
> Sort of. Unfortunately, AFAIK, Java developers decided that "pointer"
> was a dirty word and used the word "reference" instead. Java
> references really ought to have been called pointers. Java references
> have more or less the same semantics as C++ pointers (except of course
> no pointer arithmetic, etc.). That is, a C++ pointer is a "region of
> memory" distinct from the "region of memory" of the pointed-to thingy.
> Same as Java. In C++ parlance, the pointer is an object, and it points
> to a separate object.


Actually references in Java are much more abstract than pointers in C++,
even though that might not be immediately apparent.

Not only cannot you perform pointer arithmetic with Java references,
you cannot reinterpret-cast them either, which is actually a more important
limitation than just safeguarding the programmer from mistakes.

The strict rules imposed on Java references allow the JRE to perform
operations that are impossible for a C++ runtime environment to do. For
example, it allows transparent memory compaction and defragmentation
(in other words, the physical location of objects in memory may be changed
by the runtime environment without the refences to them breaking). Granted,
I don't know if any existing JRE does this, but the language fully allows
for it to be done.

This abstraction even allows for the JRE to make runtime safety checks,
such as checking that references are pointing to valid objects (they might
point to invalid objects if the Java binary is corrupted or somehow
ill-formed, possibly on purpose).

This cannot be done in C++ because pointers are literal memory addresses,
and moving an object from one memory location to another will break any
pointers pointing to it. C++ pointers cannot be made similarly abstract as
they are in Java because of all the operations that must be possible to apply
to them (such as conversion to void* and back, or reinterpret-casting to
a completely unrelated pointer type).

Brian Drummond 11-09-2011 09:49 AM

Re: Why const int& ?
 
On Wed, 09 Nov 2011 09:00:15 +0000, Juha Nieminen wrote:

> Joshua Maurice <joshuamaurice@gmail.com> wrote:
>> Unfortunately, AFAIK, Java developers decided that "pointer"
>> was a dirty word and used the word "reference" instead. Java references
>> really ought to have been called pointers.


In that respect, Java follows an older precedent than C or C++.

> Actually references in Java are much more abstract than pointers in
> C++,
> even though that might not be immediately apparent.


Likewise. ALGOL-W (from about 1963) comes to mind here.

- Brian

Travis Parks 11-12-2011 12:11 AM

Re: Why const int& ?
 
On Nov 8, 8:13*pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
> On Nov 7, 6:37*pm, Travis Parks <jehugalea...@gmail.com> wrote:
>
>
>
>
>
> > On Nov 7, 5:36*pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:

>
> > > On Nov 6, 9:00*am, Travis Parks <jehugalea...@gmail.com> wrote:

>
> > > > Also, does:

>
> > > > const int&

>
> > > > mean:

>
> > > > int const&

>
> > > > or:

>
> > > > int &const

>
> > > > Finally, what would int const&const mean? Does it make sense to mark
> > > > an int as constant, considering by nature it already is? Is this
> > > > syntax legal?

>
> > > int const & x -- a reference to const int
> > > const int & x -- a reference to const int
> > > int & const x -- ill formed code that should trigger a compiler error

>
> > > int const * x -- a (non-const) pointer to const int
> > > const int * x -- a (non-const) pointer to const int
> > > int * const x -- a const pointer to (non-const) int

>
> > Ah. That clears some things up. A trailing const only makes sense in
> > terms of pointers, not references.

>
> > So, say you had a block of code that looked like this:

>
> > vector<int> values;
> > init(values);

>
> > void init(vector<int> & values)
> > {
> > * * vector<int> v;
> > * * values = v; // assignment operator

>
> > }

>
> > How can I tell the compiler a) that I don't want to change the vector
> > and b) that I don't want the vector to be reassigned?

>
> > My guess right now is you handle both a and b the same way, since the
> > assignment operator modifies the internals of the vector.

>
> > Working in languages like C# and Java, where everything is a reference
> > type, it is strange to think that an assignment modifies the contents
> > of the original vector (copying v), rather than simply refering both
> > to the same vector.

>
> > On the other hand, pointers work the same way as reference types in
> > Java and C#, hence the ability to add the extra const onto the end.

>
> > Let me know if I'm on the right trail.

>
> Sort of. Unfortunately, AFAIK, Java developers decided that "pointer"
> was a dirty word and used the word "reference" instead. Java
> references really ought to have been called pointers. Java references
> have more or less the same semantics as C++ pointers (except of course
> no pointer arithmetic, etc.). That is, a C++ pointer is a "region of
> memory" distinct from the "region of memory" of the pointed-to thingy.
> Same as Java. In C++ parlance, the pointer is an object, and it points
> to a separate object.
> * int x; // an object
> * int* y = & x; // the pointer object y points to the int object x
>
> A C++ reference is not a distinct object. It is merely another name
> for a pre-existing object. Now, as an implementation detail, it's
> probably implemented as a pointer, but that's an implementation
> detail. You cannot make a const reference (contrast with "reference to
> const"). All references are implicitly "const" - all references are
> unchangeable. You cannot "reseat" a reference. Once a C++ reference is
> created, it "points" to the same object for the reference's lifetime.
> Any attempt to reseat the reference invokes undefined behavior (more
> or less - IIRC there might be an obscure exception or two - ignore
> that for now).
>
> So, for:
> * * void foo(vector<int> * x)
> The body of the function can reassign x to point to a different vector
> object. The caller's pointer remains unchanged no matter what.
> However, the pointed-to object may be changed, and this is visible to
> the caller. That is, pointer have "pass by value" semantics, just like
> Java references. A change to the C++ pointer object in the body does
> not affect the caller, but a change to the pointed-to object does
> affect the caller.
>
> * * void foo(vector<int> & x)
> The body of the function cannot reassign x to "point" to a different
> vector object. Any attempt to do so is undefined behavior (more or
> less - IIRC there might be an obscure exception or two - ignore that
> for now). "x" is just another name for an already existing vector
> object. Any changes to x will affect the caller.
>
> * * void foo(vector<int> const * x)
> The caller knows that the function body won't modify the vector object
> (more or less - const_casts can, and you might be able to obtain a non-
> const reference to it through some other means and modify it through
> that).
>
> * * void foo(vector<int> * const x)
> The caller doesn't care about this const. This const only affects the
> body's local pointer object which the caller does not see.
>
> * * void foo(vector<int> const & x)
> The caller knows that the function body won't modify the vector object
> (more or less - const_casts can, and you might be able to obtain a non-
> const reference to it through some other means and modify it through
> that).
>
> * * void foo(vector<int> & const x)
> Ill-formed code. References are not distinct objects from the "pointed
> to" object. They are simply another name for an existing object. The
> const there doesn't mean anything.- Hide quoted text -
>
> - Show quoted text -


These are really awesome breakdowns. Thank you. I think this is an
interest example too:

void foo(vector<int> const *& x);

This will allow the value in the pointer to be changed, but not the
vector. This would allow the function to change which vector the
caller is looking at. For completeness:

void foo(vector<int> const* const& x);

This will not allow modification of the vector or the pointer.

This really makes things clear. Just FYI, I was asking this question
because I am in the process of designing my own low-level language
that supports pointers and references. I was trying to figure out the
semantics of references and pointers.

I have been struggling on how I want to provide all the power of C
without making other features of the language unnecessarily
complicated. In OOP and functional situations, const-ness, pointers
and references can kill succinctness.

This language needs to be capable of implementing an OS with features
allowing for higher levels of abstraction. It is hard to implement an
OS without the ability to manipulate memory on a byte-by-byte basis.

Thanks again!


All times are GMT. The time now is 04:59 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.