Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #9756 > unrolled thread
| Started by | "Jarrick Chagma" <Jarrick.Chagma@your.mind.gmail.com> |
|---|---|
| First post | 2011-09-05 23:11 +1000 |
| Last post | 2011-09-08 18:53 -0700 |
| Articles | 12 — 10 participants |
Back to article view | Back to comp.lang.c++
[n00b] Different ways of representing "address" arguments "Jarrick Chagma" <Jarrick.Chagma@your.mind.gmail.com> - 2011-09-05 23:11 +1000
Re: Different ways of representing "address" arguments Saeed Amrollahi <amrollahi.saeed@gmail.com> - 2011-09-05 06:47 -0700
Re: Different ways of representing "address" arguments gwowen <gwowen@gmail.com> - 2011-09-05 06:59 -0700
Re: Different ways of representing "address" arguments Goran <goran.pusic@gmail.com> - 2011-09-05 23:57 -0700
Re: Different ways of representing "address" arguments Paul <pchristor@yahoo.co.uk> - 2011-09-06 09:04 -0700
Re: Different ways of representing "address" arguments "Thomas J. Gritzan" <phygon_antispam@gmx.de> - 2011-09-07 02:32 +0200
Re: Different ways of representing "address" arguments "Paul" <pchristor@yahoo.co.uk> - 2011-09-09 01:20 +0100
Re: Different ways of representing "address" arguments Goran <goran.pusic@gmail.com> - 2011-09-07 00:01 -0700
Re: Different ways of representing "address" arguments Paul <pchristor@yahoo.co.uk> - 2011-09-07 05:09 -0700
Re: [n00b] Different ways of representing "address" arguments Bart van Ingen Schenau <bart@ingen.ddns.info> - 2011-09-06 13:19 +0200
Re: Different ways of representing "address" arguments James Kanze <james.kanze@gmail.com> - 2011-09-06 15:29 -0700
Re: Different ways of representing "address" arguments Joshua Maurice <joshuamaurice@gmail.com> - 2011-09-08 18:53 -0700
| From | "Jarrick Chagma" <Jarrick.Chagma@your.mind.gmail.com> |
|---|---|
| Date | 2011-09-05 23:11 +1000 |
| Subject | [n00b] Different ways of representing "address" arguments |
| Message-ID | <EpydnR4coofgV_nTnZ2dnUVZ_tednZ2d@westnet.com.au> |
I am new to C++ and have a basic question. What is the semantic difference between these two: A) void foo(const int &i) B) void foo(int *i) AFAICT, both will result in the address of an integer argument being passed to foo() and in both cases the address cannot be modified. Are there any differences other than that i will need to be dereferenced in (B)? Which is preferred? -- Regards, Jarrick
[toc] | [next] | [standalone]
| From | Saeed Amrollahi <amrollahi.saeed@gmail.com> |
|---|---|
| Date | 2011-09-05 06:47 -0700 |
| Subject | Re: Different ways of representing "address" arguments |
| Message-ID | <5eb32c5f-5538-4ca3-b656-948cac5d6a6e@r21g2000yqr.googlegroups.com> |
| In reply to | #9756 |
On Sep 5, 4:11 pm, "Jarrick Chagma" <Jarrick.Cha...@your.mind.gmail.com> wrote: > I am new to C++ and have a basic question. What is the semantic difference > between these two: > > A) void foo(const int &i) > B) void foo(int *i) > They are two different approaches to reference semantics in C and C++ in B, you pass the address of and object to function foo and likely you want to change the value of the variable that i points to. It's uses in both C and C++. in A, you pass a reference to constant int (read from right to left) so you pass the actual object not a copy of it. It's uses in C++. Please note, A and B aren't exactly equivalent. The following are equivalent: A) void foo(int& i); B) void foo(int* i); or A) void bar(const int& i); B) void bar(const int* i); > AFAICT, both will result in the address of an integer argument being passed > to foo() and in both cases the address cannot be modified. From the point of implementation view, a reference is implemented using constant pointers. Are there any > differences other than that i will need to be dereferenced in (B)? Which is > preferred? > In C++, we prefer references over pointers.Use references whenever possible, and use pointers when you have to. for further information see: - Scott Meyers. More Effective C++, Item 1 - http://www.parashift.com/c++-faq/references.html > -- > Regards, > > Jarrick HTH, -- Saeed Amrollahi
[toc] | [prev] | [next] | [standalone]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2011-09-05 06:59 -0700 |
| Subject | Re: Different ways of representing "address" arguments |
| Message-ID | <7c1639f8-ae0e-47df-a937-4a5cbfcf56aa@a13g2000yqd.googlegroups.com> |
| In reply to | #9756 |
On Sep 5, 2:11 pm, "Jarrick Chagma" <Jarrick.Cha...@your.mind.gmail.com> wrote: > I am new to C++ and have a basic question. What is the semantic difference > between these two: > > A) void foo(const int &i) > B) void foo(int *i) > > AFAICT, both will result in the address of an integer argument being passed > to foo() and in both cases the address cannot be modified. That's not quite right. The argument to (A) is a reference to a constant object - its the object itself that cannot be modified. References themselves can never be modified/reseated, just as they can never be NULL (although they can refer to objects that no longer exist). Similarly, "const int *i" is a pointer to a constant object, and "int * const i" is a constant pointer to a modifiable object. > Which is preferred? In the loosest sense -- and noting that B) would be foo(const int *i) for the semantics to be fundamentally the same -- use B if C- compatibility is required, or if a NULL argument makes sense. Use A otherwise.
[toc] | [prev] | [next] | [standalone]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-09-05 23:57 -0700 |
| Subject | Re: Different ways of representing "address" arguments |
| Message-ID | <967b9c68-65e0-4587-ba69-a296472cd503@u6g2000yqa.googlegroups.com> |
| In reply to | #9756 |
On Sep 5, 3:11 pm, "Jarrick Chagma" <Jarrick.Cha...@your.mind.gmail.com> wrote: > I am new to C++ and have a basic question. What is the semantic difference > between these two: > > A) void foo(const int &i) > B) void foo(int *i) > > AFAICT, both will result in the address of an integer argument being passed > to foo() > and in both cases the address cannot be modified. Are there any > differences other than that i will need to be dereferenced in (B)? Which is > preferred? IMHO, if you see a pointer in a well-designed C++ code, it means there's a program state where said pointer can be null. That also means dealing with said null. A reference, however, is never "null", there's no such thing except in BROKEN code (e.g. a reference was created from NULL pointer). Now, note that references in C++ give access to a parameter passing by references. Not all languages have that. E.g. Pascal have it (look for "var" in function/procedure parameter list), as well as C# (look for "ref" and "out"). Java, and more notably C, do not have pass-by- reference. In C, the only way to pass-by-reference is to use a pointer. But a pointer is like an "optional reference" (NULL kinda means "here's a reference to an absent variable"). Consequence of that, and because a NULL pointer is legal code, C code tends to be fraught with checks for NULL where there should be none, and fraught with future danger to pass NULL where you shouldn't, exactly because there's no possibility to be explicit about intended pass-by- reference. Finally, some people argue against use of references for pass-by-ref in C++ code, because at the call site (foo(some_int)), you don't see that a given value can be changed, whereas, if you use a pointer, that ain't the case (foo(*some_int)), because that "*" stands out like a sore thumb. However, in good C code, if a parameter passed in by a pointer should not change inside a function, it should be declared "const", and then, you again don't really see whether it will be changed or not, you can only guess that it might. In that respect, C# does the right thing IMO, by requiring use of "ref" and "out" at a call site as well as in the declaration. To cut the long story short: when in Rome, do as Romans do. Use reference for reference parameters, pointers for "optional reference" parameters. And yes, in common implementations, "under the hood", the two are the same thing. Goran.
[toc] | [prev] | [next] | [standalone]
| From | Paul <pchristor@yahoo.co.uk> |
|---|---|
| Date | 2011-09-06 09:04 -0700 |
| Subject | Re: Different ways of representing "address" arguments |
| Message-ID | <e3f0ae81-ed39-402e-a93a-a327b071963c@r17g2000yqa.googlegroups.com> |
| In reply to | #9779 |
On Sep 6, 7:57 am, Goran <goran.pu...@gmail.com> wrote: > On Sep 5, 3:11 pm, "Jarrick Chagma" > > <Jarrick.Cha...@your.mind.gmail.com> wrote: > > I am new to C++ and have a basic question. What is the semantic difference > > between these two: > > > A) void foo(const int &i) > > B) void foo(int *i) > > > AFAICT, both will result in the address of an integer argument being passed > > to foo() > > and in both cases the address cannot be modified. Are there any > > differences other than that i will need to be dereferenced in (B)? Which is > > preferred? > > IMHO, if you see a pointer in a well-designed C++ code, it means > there's a program state where said pointer can be null. That also > means dealing with said null. > There is also the case where polymorphic behavour is expected. The function may take a Shape pointer parameter type, where a Circle or a Polygon is expected.
[toc] | [prev] | [next] | [standalone]
| From | "Thomas J. Gritzan" <phygon_antispam@gmx.de> |
|---|---|
| Date | 2011-09-07 02:32 +0200 |
| Subject | Re: Different ways of representing "address" arguments |
| Message-ID | <j46e3v$1r9$1@newsreader4.netcologne.de> |
| In reply to | #9808 |
Am 06.09.2011 18:04, schrieb Paul: > On Sep 6, 7:57 am, Goran<goran.pu...@gmail.com> wrote: >> On Sep 5, 3:11 pm, "Jarrick Chagma" >> >> <Jarrick.Cha...@your.mind.gmail.com> wrote: >>> I am new to C++ and have a basic question. What is the semantic difference >>> between these two: >> >>> A) void foo(const int&i) >>> B) void foo(int *i) The const in A) applies to the referred to integer. In A) you cannot change the value, while in B) you can change the pointed to value and the pointer itself. (well, you can only change the local copy of the pointer, but not the pointer in the calling function.) >>> AFAICT, both will result in the address of an integer argument being passed >>> to foo() >>> and in both cases the address cannot be modified. Are there any >>> differences other than that i will need to be dereferenced in (B)? Which is >>> preferred? Prefer references unless you need pointer semantics. Prefer const unless you need to modify. >> IMHO, if you see a pointer in a well-designed C++ code, it means >> there's a program state where said pointer can be null. That also >> means dealing with said null. >> > There is also the case where polymorphic behavour is expected. > The function may take a Shape pointer parameter type, where a Circle > or a Polygon is expected. Goran wanted to point out a difference between pointers and references. A reference cannot (legally) be null like a pointer, but polymorphic behaviour works equally with references and pointers. -- Thomas
[toc] | [prev] | [next] | [standalone]
| From | "Paul" <pchristor@yahoo.co.uk> |
|---|---|
| Date | 2011-09-09 01:20 +0100 |
| Subject | Re: Different ways of representing "address" arguments |
| Message-ID | <j4bm57$l1f$1@adenine.netfront.net> |
| In reply to | #9857 |
"Thomas J. Gritzan" <phygon_antispam@gmx.de> wrote in message news:j46e3v$1r9$1@newsreader4.netcologne.de... > Am 06.09.2011 18:04, schrieb Paul: >> On Sep 6, 7:57 am, Goran<goran.pu...@gmail.com> wrote: >>> On Sep 5, 3:11 pm, "Jarrick Chagma" >>> >>> <Jarrick.Cha...@your.mind.gmail.com> wrote: >>>> I am new to C++ and have a basic question. What is the semantic >>>> difference >>>> between these two: >>> >>>> A) void foo(const int&i) >>>> B) void foo(int *i) > > The const in A) applies to the referred to integer. In A) you cannot > change the value, while in B) you can change the pointed to value and the > pointer itself. > > (well, you can only change the local copy of the pointer, but not the > pointer in the calling function.) > >>>> AFAICT, both will result in the address of an integer argument being >>>> passed >>>> to foo() >>>> and in both cases the address cannot be modified. Are there any >>>> differences other than that i will need to be dereferenced in (B)? >>>> Which is >>>> preferred? > > Prefer references unless you need pointer semantics. Prefer const unless > you need to modify. > >>> IMHO, if you see a pointer in a well-designed C++ code, it means >>> there's a program state where said pointer can be null. That also >>> means dealing with said null. >>> >> There is also the case where polymorphic behavour is expected. >> The function may take a Shape pointer parameter type, where a Circle >> or a Polygon is expected. > > Goran wanted to point out a difference between pointers and references. > > A reference cannot (legally) be null like a pointer, but polymorphic > behaviour works equally with references and pointers. > Yes I realise he was pointing out the difference between pointers and references. I was mainly responding to what he said about seeing a pointer in code means there will be a null state someplace, which is actually what I usually think myself. I was looking for a senario where this assumption is not always a prudent assumption. As you correctly pointed out my polymorphism example was not an ideal scenario as I was overlooking the fact that this can also be done using references. Apart from the obvious scenario of re-allocating a different object to the pointer, and the benefits of having a possible null. There is another scenario where it may be beneficial to prefer a pointer over a reference thus it is not always prudent to assume the pointer may be null. That is when the argument is a pointer to an array. --- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---
[toc] | [prev] | [next] | [standalone]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-09-07 00:01 -0700 |
| Subject | Re: Different ways of representing "address" arguments |
| Message-ID | <f2ec119d-443f-4271-903f-6fa1b815f04b@l2g2000vbn.googlegroups.com> |
| In reply to | #9808 |
On Sep 6, 6:04 pm, Paul <pchris...@yahoo.co.uk> wrote:
> On Sep 6, 7:57 am, Goran <goran.pu...@gmail.com> wrote:
>
>
>
>
>
>
>
> > On Sep 5, 3:11 pm, "Jarrick Chagma"
>
> > <Jarrick.Cha...@your.mind.gmail.com> wrote:
> > > I am new to C++ and have a basic question. What is the semantic difference
> > > between these two:
>
> > > A) void foo(const int &i)
> > > B) void foo(int *i)
>
> > > AFAICT, both will result in the address of an integer argument being passed
> > > to foo()
> > > and in both cases the address cannot be modified. Are there any
> > > differences other than that i will need to be dereferenced in (B)? Which is
> > > preferred?
>
> > IMHO, if you see a pointer in a well-designed C++ code, it means
> > there's a program state where said pointer can be null. That also
> > means dealing with said null.
>
> There is also the case where polymorphic behavour is expected.
> The function may take a Shape pointer parameter type, where a Circle
> or a Polygon is expected.
References exhibit polymorphic behavior just like pointers. Two issues
are completely orthogonal. E.g.
class Shape { virtual void Draw() = 0 };
class Circle { virtual void Draw() { cout << "c"; };
class Rectangle { virtual void Draw() { cout << "r"; };
void f(Shape& s)
{
s.Draw();
}
Circle c;
Rectangle r;
f(c);
f(r);
prints "c" and "r". You don't _need_ pointers there.
Goran.
P.S. Are you the guy who have been insulting me before, saying I don'
know my stuff? The above is pretty basic C++. The nerve of some
people...
[toc] | [prev] | [next] | [standalone]
| From | Paul <pchristor@yahoo.co.uk> |
|---|---|
| Date | 2011-09-07 05:09 -0700 |
| Subject | Re: Different ways of representing "address" arguments |
| Message-ID | <d54405d0-7164-4d34-966d-70e7a0a7e9da@d18g2000yqm.googlegroups.com> |
| In reply to | #9867 |
On Sep 7, 8:01 am, Goran <goran.pu...@gmail.com> wrote:
> On Sep 6, 6:04 pm, Paul <pchris...@yahoo.co.uk> wrote:
>
>
>
>
>
> > On Sep 6, 7:57 am, Goran <goran.pu...@gmail.com> wrote:
>
> > > On Sep 5, 3:11 pm, "Jarrick Chagma"
>
> > > <Jarrick.Cha...@your.mind.gmail.com> wrote:
> > > > I am new to C++ and have a basic question. What is the semantic difference
> > > > between these two:
>
> > > > A) void foo(const int &i)
> > > > B) void foo(int *i)
>
> > > > AFAICT, both will result in the address of an integer argument being passed
> > > > to foo()
> > > > and in both cases the address cannot be modified. Are there any
> > > > differences other than that i will need to be dereferenced in (B)? Which is
> > > > preferred?
>
> > > IMHO, if you see a pointer in a well-designed C++ code, it means
> > > there's a program state where said pointer can be null. That also
> > > means dealing with said null.
>
> > There is also the case where polymorphic behavour is expected.
> > The function may take a Shape pointer parameter type, where a Circle
> > or a Polygon is expected.
>
> References exhibit polymorphic behavior just like pointers. Two issues
> are completely orthogonal. E.g.
>
> class Shape { virtual void Draw() = 0 };
> class Circle { virtual void Draw() { cout << "c"; };
> class Rectangle { virtual void Draw() { cout << "r"; };
>
> void f(Shape& s)
> {
> s.Draw();}
>
> Circle c;
> Rectangle r;
> f(c);
> f(r);
>
> prints "c" and "r". You don't _need_ pointers there.
Ah ok I forgot you can do that.
>
> Goran.
>
> P.S. Are you the guy who have been insulting me before, saying I don'
> know my stuff? The above is pretty basic C++. The nerve of some
> people...- Hide quoted text -
Dunno when I am supposed to have insulted you. Perhaps if I've said
"you don't know your stuff" you have made some silly argument that
made that appear to be the case. I wouldn't take that as an insult its
only a small gibe.
Please link the message you are talking about.
> - Show quoted text -
[toc] | [prev] | [next] | [standalone]
| From | Bart van Ingen Schenau <bart@ingen.ddns.info> |
|---|---|
| Date | 2011-09-06 13:19 +0200 |
| Message-ID | <j44vjv$6pp$1@localhost.localdomain> |
| In reply to | #9756 |
Jarrick Chagma Wrote: > I am new to C++ and have a basic question. What is the semantic > difference > > between these two: > > A) void foo(const int &i) > B) void foo(int *i) > > AFAICT, both will result in the address of an integer argument being > passed to foo() and in both cases the address cannot be modified. This is not neccesarilly true. In version A, the name 'i' inside foo is an alias to the argument passed to foo in the call. The most common way for a compiler to implement these semantics is by actually passing the address of the argument, but there is no requirement to do it that way. > Are there any differences other than that i will need to be > dereferenced in (B)? Which is preferred? One major difference between A and B, as they are declared now, is that in A the object that 'i' refers to can not be changed from within foo, while in B the object that 'i' points at *can* be changed. For indicating which is preferred, lets look at all the ways you can pass arguments: - By value: void foo(int i): This is preferred when passing (small) objects/values to a function, where the function is not expected to change the passed object. - By const reference: void foo(const int& i): This is preferred when passing large(-ish) objects/values to a function, where the function is not supposed to change the passed object. - By pointer: void foo(const int* i) or void foo(int* i): This is preferred when you need a mechanism to indicate the absence of a value. Use the first variant if the function is not supposed to update the argument. - By non-const reference: void foo(int& i): This is preferred when foo is supposed to update the argument and the argument is mandatory. > > -- > Regards, > > Jarrick > Bart v Ingen Schenau
[toc] | [prev] | [next] | [standalone]
| From | James Kanze <james.kanze@gmail.com> |
|---|---|
| Date | 2011-09-06 15:29 -0700 |
| Subject | Re: Different ways of representing "address" arguments |
| Message-ID | <c1781dea-ed43-49d5-8e86-f1923d57a209@a12g2000yqi.googlegroups.com> |
| In reply to | #9798 |
On Sep 6, 12:19 pm, Bart van Ingen Schenau <b...@ingen.ddns.info> wrote: > Jarrick Chagma Wrote: > > I am new to C++ and have a basic question. What is the semantic > > difference > > between these two: > > A) void foo(const int &i) > > B) void foo(int *i) > > AFAICT, both will result in the address of an integer argument being > > passed to foo() and in both cases the address cannot be modified. > This is not neccesarilly true. In version A, the name 'i' inside foo is an > alias to the argument passed to foo in the call. The most common way for a > compiler to implement these semantics is by actually passing the address of > the argument, but there is no requirement to do it that way. > > Are there any differences other than that i will need to be > > dereferenced in (B)? Which is preferred? > One major difference between A and B, as they are declared > now, is that in A the object that 'i' refers to can not be > changed from within foo, while in B the object that 'i' points > at *can* be changed. Another major difference is that you can pass a temporary (the results of an expression or a function) to A; you can't to B. And yet another difference is that you can pass a null pointer to B; you can't to A. Not to mention the different syntax at the call site. All things taken together, there are probably more differences than similarities. -- James Kanze
[toc] | [prev] | [next] | [standalone]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2011-09-08 18:53 -0700 |
| Subject | Re: Different ways of representing "address" arguments |
| Message-ID | <3d257d87-ac99-4c0c-b59e-37a7c05634d9@e20g2000prn.googlegroups.com> |
| In reply to | #9756 |
On Sep 5, 6:11 am, "Jarrick Chagma" <Jarrick.Cha...@your.mind.gmail.com> wrote: > I am new to C++ and have a basic question. What is the semantic difference > between these two: > > A) void foo(const int &i) > B) void foo(int *i) > > AFAICT, both will result in the address of an integer argument being passed > to foo() and in both cases the address cannot be modified. Are there any > differences other than that i will need to be dereferenced in (B)? Which is > preferred? That is an incorrect description of what's going on. Using your loose terminology, void foo(int & i); "passes the address of an int object, and the address cannot be modified". Once you create a reference, it cannot be changed to refer to something else. The following means something different. void foo(const int & i) The proper way to read the argument type is "a reference to a const int". References are always unchangeable, but what it refers to can be changeable. int & The reference is not changeable to "point" to another object. However, you can change the refered-to object. const int & int const & The reference is not changeable to "point" to another object. Also, you cannot change the refered-to object. int * You can change which object the pointer points to. Also, you can change the pointed-to object. const int * int const * You can change which object the pointer points to. However, you cannot change the pointed-to object. int * const You cannot change which object the pointer points to. However, you can change the pointed-to object. Your original function void foo(int * ); takes a pointer by value. The caller's argument pointer object will not be changed. However, the caller's pointed-to object can be changed. With void foo(const int & ); This takes a reference to an int object, specifically a reference to const int. The caller's int object will not be changed (unless const_cast). The proper things to compare are: void foo(int & ); void foo(int * ); Here, on nearly any implementation, they will be implemented with the same assembly. To finally answer your question, the difference is largely syntactic sugar and convention, and I won't repeat most of what they said here. Do note as explained else-thread that it's undefined behavior to create a "null" reference, so the body of "void foo( int & )" would not have to deal with the possibility of null, whereas "void foo(int * )" can legitimately be given a null argument. But of course, you could document the function as taking only non- nulls, and put the burden on the caller to ensure only non-null pointers are passed to it. Convention. PS: This is assuming that we're following basic const correctness. With no const correctness, or with const_cast-ing, then some of what I said above does not apply. Do note that any attempt to make a reference point to a different object is still undefined behavior.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web