473,387 Members | 3,033 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

What does the initialization of a reference object do?

Hi all,

The results from following codes got me a bit confused.

#include <stdio.h>
#include <iostream>

using namespace std;

struct A {

A () { cout << "A() ctor!" << endl; };

~A() { cout << "~A() dtor!" << endl; };

void foo () { printf("this=%p\n", this); };

int x, y;

};
main ()
{

A& a = a;
cout << "&a=" << &a << endl;
a.foo(); // is it legal here?
// a.x = 10; // illegal here
// a.y = 20;

A a1;
A& a2 = a1;
cout << "&a1=" << &a1 << endl;
cout << "a2."; a2.foo();

}

gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
g++ -o foo foo.cpp
foo

&a=0x80488ce
this=0x80488ce
A() ctor!
&a1=0xbffff0d0
a2.this=0xbffff0d0
~A() dtor!

What does the initialization of a reference object do? Suppose the
initialization of reference is simply has its "this" pointer to the
target object. This does not call constructor, which is true. For
self-referenced "A& a = a", how can its "this" pointer be correctly
bound to member function foo()? As seen, "a.foo()" works OK! Isn't it
supposed to be illegal?

Any help would be appreciated.

Gary

May 27 '06 #1
9 2441
* ziman137:
Hi all,

The results from following codes got me a bit confused.

#include <stdio.h>
Unnecessary.

#include <iostream>

using namespace std;

struct A {

A () { cout << "A() ctor!" << endl; };

~A() { cout << "~A() dtor!" << endl; };

void foo () { printf("this=%p\n", this); };
Just use standard std::cout.

int x, y;
Not used. Please post not just complete, but minimal, examples. See
the FAQ item "How do I post a question about code that doesn't work
correctly?" currently at <url:
http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8>

};
main ()
Should not compile; see the FAQ item "Should I use void main() or int
main()?" currently at <url:
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.3>

{

A& a = a;


Should not compile; §8.5.3/1 "A variable declared to be a T&, that is
"reference to type T" (8.3.2), shall be initialized by an object", also
§8.3.2/4 "A reference shall be initialized to refer to a valid object or
function", and 'a' is not a valid object.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
May 27 '06 #2
Alf P. Steinbach wrote:
* ziman137:
Hi all,

The results from following codes got me a bit confused.

#include <stdio.h>
Unnecessary.

#include <iostream>

using namespace std;

struct A {

A () { cout << "A() ctor!" << endl; };

~A() { cout << "~A() dtor!" << endl; };

void foo () { printf("this=%p\n", this); };


Just use standard std::cout.

int x, y;


Not used. Please post not just complete, but minimal, examples. See
the FAQ item "How do I post a question about code that doesn't work
correctly?" currently at <url:
http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8>

};
main ()


Should not compile; see the FAQ item "Should I use void main() or int
main()?" currently at <url:
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.3>


Thanks. I have corrected all above and re-posted my code and results
below.
{

A& a = a;


Should not compile; §8.5.3/1 "A variable declared to be a T&, that is
"reference to type T" (8.3.2), shall be initialized by an object", also
§8.3.2/4 "A reference shall be initialized to refer to a valid object or
function", and 'a' is not a valid object.


Thanks for your answer. I did understand this.

It should not compile? If a reference object is assumed to be just
initialized in the manner of an internal pointer, which points to the
target "object" address, or is assigned by target "this" pointer, it
may well compile. No doubt it is a bad statement - my question is, how
exactly does C++ standard prevent this "should-not" from happening?

By the way, this was exactly where I got confused. My problem was, it
did compile using GNU C++ on Linux (Redhat, see below). Not only being
compiled, it also invokes "a.foo()" OK. Could you, or someone else,
please help me understand whether this is a compiler implementation
issue, or this has something to do with the reference initialization in
ISO C++ standard?

Thankfully,
Gary

------------

PS. Corrected Code to Conform to Group Posting Standard

// foo.cpp
#include <iostream>
using namespace std;

struct A {

A () { cout << "A() ctor!" << endl; };
~A() { cout << "~A() dtor!" << endl; };

void foo () { cout << "this=" << this << endl; };

};
int main ()
{

A& a = a; // it does compile with GNU C++ compiler
cout << "&a=" << &a << endl;
a.foo(); // is it legal here?

A a1;
A& a2 = a1;
cout << "&a1=" << &a1 << endl;
cout << "a2."; a2.foo();

return 0;

}

gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) g++ -o foo foo.cpp
foo

&a=0x80488ba
this=0x80488ba
A() ctor!
&a1=0xbfffd8e0
a2.this=0xbfffd8e0
~A() dtor!

May 27 '06 #3
* ziman137:
Alf P. Steinbach wrote:
{

A& a = a; Should not compile; §8.5.3/1 "A variable declared to be a T&, that is
"reference to type T" (8.3.2), shall be initialized by an object", also
§8.3.2/4 "A reference shall be initialized to refer to a valid object or
function", and 'a' is not a valid object.


Thanks for your answer. I did understand this.

It should not compile? If a reference object is assumed to be just
initialized in the manner of an internal pointer, which points to the
target "object" address, or is assigned by target "this" pointer, it
may well compile. No doubt it is a bad statement - my question is, how
exactly does C++ standard prevent this "should-not" from happening?


Sorry, bad wording or perhaps thinking: it shouldn't compile /cleanly/.

The C++ standard can't prevent it from happening, because a reference
that's not to a valid object can be produced by code that's impossible
to analyse -- e.g., whether the reference is valid or not could depend
on the solution to some intractable mathematical problem.

The wording "shall" above means that if the code does produce a
rerefence that's not to a valid object, it has Undefined Behavior.

A quality compiler will detect the most flagrant violations, such as the
above, and issue a diagnostic (warning or error), just as with e.g.
calling a pure virtual function from a constructor -- which is the
same kind of impossible-to-analyze problem for the general case. Comeau
Online 4.3.3 with default settings warns about your code. Visual C++
7.1 with /W4 warns. MingW g++ 3.4.4 with -Wall and -pedantic warns.

With some compilers you have to instruct them to issue warnings. Since
I have that by default I don't know whether the compilers mentioned will
issue warnings if you don't up the default warning level. But that's
tool usage.

By the way, this was exactly where I got confused. My problem was, it
did compile using GNU C++ on Linux (Redhat, see below). Not only being
compiled, it also invokes "a.foo()" OK.


Not OK: undefined behavior means undefined behavior, including what one
might "expect" were it not for the undefined behavior.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
May 27 '06 #4
"ziman137" <ga********@yahoo.com> wrote in message
news:11*********************@38g2000cwa.googlegrou ps.com
Alf P. Steinbach wrote:

A& a = a;
Should not compile; §8.5.3/1 "A variable declared to be a T&, that is
"reference to type T" (8.3.2), shall be initialized by an object",
also §8.3.2/4 "A reference shall be initialized to refer to a valid
object or function", and 'a' is not a valid object.


Thanks for your answer. I did understand this.

It should not compile? If a reference object is assumed to be just
initialized in the manner of an internal pointer, which points to the
target "object" address, or is assigned by target "this" pointer, it
may well compile. No doubt it is a bad statement - my question is, how
exactly does C++ standard prevent this "should-not" from happening?

By the way, this was exactly where I got confused. My problem was, it
did compile using GNU C++ on Linux (Redhat, see below). Not only being
compiled, it also invokes "a.foo()" OK. Could you, or someone else,
please help me understand whether this is a compiler implementation
issue, or this has something to do with the reference initialization
in ISO C++ standard?


It doesn't have anything specifically to do with references.

A a = a;

will also compile on VC++ 8 and Comeau online. It is a nonsense, just like
your code. It involves undefined behaviour, but lots of things that involve
undefined behaviour still compile. Some of them also run correctly. That is
what undefined means --- the outcome could be anything. Empirical
observation suggests that nonsense initializations will "work" if your class
does not in fact have anything that needs initializing (or if you make no
use of the stuff that does).

Likewise your

a.foo();

is undefined behaviour that you can sometimes get away with.

Try this:

A * ptr;

ptr->foo();

That probably works too.

PS. Corrected Code to Conform to Group Posting Standard

// foo.cpp
#include <iostream>
using namespace std;

struct A {

A () { cout << "A() ctor!" << endl; };
~A() { cout << "~A() dtor!" << endl; };

void foo () { cout << "this=" << this << endl; };

};
int main ()
{

A& a = a; // it does compile with GNU C++ compiler
cout << "&a=" << &a << endl;
a.foo(); // is it legal here?

A a1;
A& a2 = a1;
cout << "&a1=" << &a1 << endl;
cout << "a2."; a2.foo();

return 0;

}

gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
g++ -o foo foo.cpp
foo

&a=0x80488ba
this=0x80488ba
A() ctor!
&a1=0xbfffd8e0
a2.this=0xbfffd8e0
~A() dtor!


Running this is debug mode under VC++ 8 gives:

&a=CCCCCCCC
this=CCCCCCCC
A() ctor!
&a1=0012FF37
a2.this=0012FF37
~A() dtor!

The CCCCCCCC address values indicate uninitialized data (in debug mode only,
the compiler initializes the variables to CCCCCCCC, so that if they stay
that way, then you know the program has failed to initialize them).
--
John Carson
May 27 '06 #5
"ziman137" <ga********@yahoo.com> wrote in message
news:11*********************@38g2000cwa.googlegrou ps.com
Alf P. Steinbach wrote:

A& a = a;
Should not compile; §8.5.3/1 "A variable declared to be a T&, that is
"reference to type T" (8.3.2), shall be initialized by an object",
also §8.3.2/4 "A reference shall be initialized to refer to a valid
object or function", and 'a' is not a valid object.


Thanks for your answer. I did understand this.

It should not compile? If a reference object is assumed to be just
initialized in the manner of an internal pointer, which points to the
target "object" address, or is assigned by target "this" pointer, it
may well compile. No doubt it is a bad statement - my question is, how
exactly does C++ standard prevent this "should-not" from happening?

By the way, this was exactly where I got confused. My problem was, it
did compile using GNU C++ on Linux (Redhat, see below). Not only being
compiled, it also invokes "a.foo()" OK. Could you, or someone else,
please help me understand whether this is a compiler implementation
issue, or this has something to do with the reference initialization
in ISO C++ standard?


It doesn't have anything specifically to do with references.

A a = a;

will also compile on VC++ 8 and Comeau online. It is a nonsense, just like
your code. It involves undefined behaviour, but lots of things that involve
undefined behaviour still compile. Some of them also run correctly. That is
what undefined means --- the outcome could be anything. Empirical
observation suggests that nonsense initializations will "work" if your class
does not in fact have anything that needs initializing (or if you make no
use of the stuff that does).

Likewise your

a.foo();

is undefined behaviour that you can sometimes get away with.

Try this:

A * ptr;

ptr->foo();

That probably works too.

PS. Corrected Code to Conform to Group Posting Standard

// foo.cpp
#include <iostream>
using namespace std;

struct A {

A () { cout << "A() ctor!" << endl; };
~A() { cout << "~A() dtor!" << endl; };

void foo () { cout << "this=" << this << endl; };

};
int main ()
{

A& a = a; // it does compile with GNU C++ compiler
cout << "&a=" << &a << endl;
a.foo(); // is it legal here?

A a1;
A& a2 = a1;
cout << "&a1=" << &a1 << endl;
cout << "a2."; a2.foo();

return 0;

}

gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
g++ -o foo foo.cpp
foo

&a=0x80488ba
this=0x80488ba
A() ctor!
&a1=0xbfffd8e0
a2.this=0xbfffd8e0
~A() dtor!


Running this is debug mode under VC++ 8 gives:

&a=CCCCCCCC
this=CCCCCCCC
A() ctor!
&a1=0012FF37
a2.this=0012FF37
~A() dtor!

The CCCCCCCC address values indicate uninitialized data (in debug mode only,
the compiler initializes the variables to CCCCCCCC, so that if they stay
that way, then you know the program has failed to initialize them).
--
John Carson
May 27 '06 #6
ziman137 wrote:
Hi all,

The results from following codes got me a bit confused.

#include <stdio.h>
#include <iostream>

using namespace std;

struct A {

A () { cout << "A() ctor!" << endl; };

~A() { cout << "~A() dtor!" << endl; };

void foo () { printf("this=%p\n", this); };
a reference itself returns a size of 1
int x, y;

};
always, always initialize your members:

#include <iostream>

struct A
{
A() : m_x(0), m_y(0) { std::cout << "default ctor\n"; }
A(int x, int y) : m_x(x), m_y(y) { std::cout << "param ctor\n"; }
~A() { std::cout << "~dtor\n"; }
private:
int x;
int y;
};


main ()
int main()
{

A& a = a;
cout << "&a=" << &a << endl;
a.foo(); // is it legal here?
// a.x = 10; // illegal here
// a.y = 20;
illegal, undefined, a reference must be initialized with a valid object.
C++ is not about side effects particular to your platform/compiler.

A a1;
A& a2 = a1;
cout << "&a1=" << &a1 << endl;
cout << "a2."; a2.foo();

}

gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
g++ -o foo foo.cpp
foo &a=0x80488ce
this=0x80488ce
A() ctor!
&a1=0xbffff0d0
a2.this=0xbffff0d0
~A() dtor!

What does the initialization of a reference object do? Suppose the
initialization of reference is simply has its "this" pointer to the
target object. This does not call constructor, which is true. For
self-referenced "A& a = a", how can its "this" pointer be correctly
bound to member function foo()? As seen, "a.foo()" works OK! Isn't it
supposed to be illegal?


You don't create objects by initialising a reference to a temporary.

a reference is an alias. Just the same as your nickname. Whether i ask
ziman, ganxu or gary to run(): it doesn't matter - the same person is
being asked to run(). For all intensive purposes there is no difference
between a reference and its target. Both share the same this.

Any help would be appreciated.

Gary


What you do need to remember is:
a) a reference cannot be un-initialized.
b) a reference is permanently bound (it can't refer to any other object).
c) a reference can extend the lifetime of an object.
d) references rids a C++ programer of pointer bugs.
May 27 '06 #7
Hi all,

I appreciate all your responses.

By discussing so far, I'd like to clarify my question a bit. My
original intent was to understand what happens "under the hood", when
initializing a reference object by an existing object. say,

class A {
A() {};
// ...
};
int main()
{
A a1;
A& a2 = a1; // What happens here under the hood?
//...
return 0;
}

I wrote the piece of bad code as shown before to explore/manifest what
might be going on when we initialize a reference object. It is
understood that this way to explore/manifest what's going under the
hood runs into the danger of confusion. That is why I was posting my
question here. In the following code,

class A {
A() {};
void foo() {};
// ...
};

int main()
{
A& a = a; // bad
a.foo(); // illegal
return 0;
}

Here we say that, because "A& a = a;" is a bad initialization, so
"a.foo();" is an undefined behavior. It is a very general explanation.
Please be reminded that my intention here is not to understand what
happens in above bad code, but to understand what happens in any legal
and good reference initialization. Yes, a good analogy to reference is
just like the "alias" to a single existing object. However, when you
store any reference (one alias), what do you actually store in C++?
Just simply an internal pointer to the singleton object, or anything
more than that? That was my real intention and question. Please keep
helping me, and any input is welcome.

Thanks again,
Gary

May 27 '06 #8
On Sat, 27 May 2006 15:39:02 -0700, ziman137 wrote:
Hi all,

I appreciate all your responses.

By discussing so far, I'd like to clarify my question a bit. My
original intent was to understand what happens "under the hood", when
initializing a reference object by an existing object. say,

class A {
A() {};
// ...
};
int main()
{
A a1;
A& a2 = a1; // What happens here under the hood?
//...
return 0;
}


The mechanics are not specified by the C++ language, only the semantics.
Compiler vendors are free to implement references however they like, so
long as the results comply with the specified semantics.

Your best bet is to write a short program -- like that one there -- and
examine the compiler's output. That will tell you what happens under that
specific compiler on that platform.

For instance, g++, the GNU C++ compiler, can be coerced into generating an
assembler listing corresponding to a program containing line numbering
information for comparison with the original source with
g++ -S -g foo.c -o foo.S

Other compilers may have similar options. Alternately, there are tools
for examining the resulting object file from normal compilation.

-Owen
May 27 '06 #9
ziman137 posted:
int main()
{
A a1;
A& a2 = a1; // What happens here under the hood?

In this particular instance, I would imagine what goes on under the hood is
very similar to:

#define a2 a1
If you're passing by reference, or returning by reference, then I would
imagine that the "hidden pointers" concept comes into play.

A fruitful exercise for trying to understand out how C++ works under the
hood, is to write a C program which emulates those features.

Here's an example of C code I wrote to emulate virtual functions:

http://groups.google.ie/group/comp.l...328d25d?hl=en&
-Tomás
May 27 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Qin Chen | last post by:
I will present very long code, hope someone will read it all, and teach me something like tom_usenet. This question comes to me when i read <<Think in C++>> 2nd, chapter 10 , name control,...
6
by: Srini | last post by:
Pardon me if this is trivial. I think I read somewhere that statements like this cause undefined behavior. int n = n; How is the above statement different from int n(n);
3
by: Anoj Kumar | last post by:
Hi All , can anyone tell me what is the difference between the following declaration and how it affects application performance. 1. Dim cn As ADODB.Connection Set cn = New ADODB.Connection
23
by: Jess | last post by:
Hello, I understand the default-initialization happens if we don't initialize an object explicitly. I think for an object of a class type, the value is determined by the constructor, and for...
6
by: Jack | last post by:
I have a set of functions to wrap a library. For example, mylib_init() mylib_func() mylib_exit() or handle = mylib_init() mylib_func(handle)
11
by: venkatagmail | last post by:
I have problem understanding pass by value and pass by reference and want to how how they are or appear in the memory: I had to get my basics right again. I create an array and try all possible...
10
by: subramanian100in | last post by:
Consider the following code: #include <iostream> #include <cstdlib> using namespace std; int main() { const double& ref = 100;
4
by: subramanian100in | last post by:
Suppose I have #include <cstdlib> #include <iostream> using namespace std; class Test { public:
5
by: Vols | last post by:
class A{ public: int x; }; class B : public A{ public: int y; }; void foo()
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.