473,387 Members | 1,863 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 happen with this 'B()'?

class A{
public:
int x;
};
class B : public A{
public:
int y;
};

void foo()
{
A &a1 = B();
A *a2 = &B();
}

what happen with those 'B()'. I've never seen this before. Where can I
get the reference for this? Thanks

Vol
Jun 27 '08 #1
5 1946
Vols wrote:
class A{
public:
int x;
};
class B : public A{
public:
int y;
};

void foo()
{
A &a1 = B();
A *a2 = &B();
This line is dangerous and your compiler should issue a warning. You are
setting a pointer to a temporary object. After this line is done, a2 will
point to an object that's been destructed causing undefined behavior if you
attempt to dereference a2.

I'm not sure about the previous line, I know that there is something about
references pointing to a temporary that will extend the lfietime of the
temporary, but I'm not sure if this case fits the bill or not.

B() simply creates a temporary instance of class B default initialized.

}

what happen with those 'B()'. I've never seen this before. Where can I
get the reference for this? Thanks

Vol


--
Jim Langston
ta*******@rocketmail.com
Jun 27 '08 #2
On Apr 24, 1:13 am, Vols <volunte...@gmail.comwrote:
class A{
public:
int x;
};
class B : public A{
public:
int y;
};
void foo()
{
A &a1 = B();
A *a2 = &B();
}

what happen with those 'B()'. I've never seen this before.
Me neither. Both lines in foo() are illegal in C++, and require
a diagnostic. (Much to my surprise, g++ only generates a
warning on the second, and Sun CC doesn't complain about
either! Which is IMHO simply not acceptable. Particularly the
second, which has never been legal C++.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #3
Hello,

James Kanze wrote:
On Apr 24, 1:13 am, Vols <volunte...@gmail.comwrote:
>class A{
public:
int x;
};
>class B : public A{
public:
int y;
};
>void foo()
{
A &a1 = B();
A *a2 = &B();
}

what happen with those 'B()'. I've never seen this before.

Me neither. Both lines in foo() are illegal in C++, and require
a diagnostic. (Much to my surprise, g++ only generates a
warning on the second, and Sun CC doesn't complain about
either! Which is IMHO simply not acceptable. Particularly the
second, which has never been legal C++.)
Can't follow that. All g++-3.3.6, 4.2.1, and 4.3.0 make the first line
in foo an error and the second a warning without any special settings.
The first line is the one that assigns reference to a temporary to a
non-const reference type, which cannot work. The second line seems to
have the same problem with const pointer and non-const pointer at
first.

liftim1.cc: In function ?void foo()?:
liftim1.cc:12: error: invalid initialization of non-const reference of
type ?A&? from a temporary of type ?B?
liftim1.cc:13: warning: taking address of temporary

A temporary object is not a const object by definition if there is no
const in the declaration. The standard mandates that assigning a
temorary to a non-const reference is not allowed, but this decision is
kind of deliberate, because it would produce hard to detect errors most
of the time. But taking the pointer is not the same es taking a
reference. Using that pointer could be problematic, especially
dereferencing, but the heuristical warning is the best one can hope for
when taking the address alone.

Bernd Strieder

Jun 27 '08 #4
Bernd Strieder wrote:
James Kanze wrote:
On Apr 24, 1:13 am, Vols <volunte...@gmail.comwrote:
class A{
public:
int x;
};
class B : public A{
public:
int y;
};
void foo()
{
A &a1 = B();
A *a2 = &B();
}
what happen with those 'B()'. I've never seen this before.
Me neither. Both lines in foo() are illegal in C++, and require
a diagnostic. (Much to my surprise, g++ only generates a
warning on the second, and Sun CC doesn't complain about
either! Which is IMHO simply not acceptable. Particularly the
second, which has never been legal C++.)
Can't follow that.
Can't follow what? That it's illegal, or that some compilers
accept it.
All g++-3.3.6, 4.2.1, and 4.3.0 make the first line in foo an
error and the second a warning without any special settings.
According to the standard, both are errors. The first was
allowed in very early versions of C++; it was found to cause
problems, and was banned sometime in the late 1980's (before the
standardization effort even began). I can understand compilers
in the early 1990's only giving a warning (so as not to break
existing code); I can even understand a compiler today having
options which would only make it a warning. But silently
accepting it, as Sun CC did? Something's wrong.

The second takes the address of an lvalue. That's never been
legal, not since K&R C. I can't understand any compiler not
making it a hard error.

(Note that the first can be made legal with a user defined
conversion to an lvalue in the class, and the second can be made
legal with a user defined operator&. Neither are present in the
example, however.)
The first line is the one that assigns reference to a
temporary to a non-const reference type, which cannot work.
Strictly speaking: neither line "assigns" anything. The first
line initializes a non-const reference with an rvalue; that's
forbidden by §8.5.3/5. The second takes the address of an
lvalue; that's forbidden by §5.3.1/2. (And it would also be an
initialization, rather than an assignment. Although in the case
of pointers, unlike references, the difference is neglible.)
The second line seems to have the same problem with const
pointer and non-const pointer at first.
liftim1.cc: In function ?void foo()?:
liftim1.cc:12: error: invalid initialization of non-const reference of
type ?A&? from a temporary of type ?B?
liftim1.cc:13: warning: taking address of temporary
A temporary object is not a const object by definition if
there is no const in the declaration.
Which isn't really relevant here.
The standard mandates that assigning a temorary to a non-const
reference is not allowed, but this decision is kind of
deliberate, because it would produce hard to detect errors
most of the time.
It's very deliberate, because it actually did produce hard to
detect errors a lot of times.
But taking the pointer is not the same es taking a reference.
Using that pointer could be problematic, especially
dereferencing, but the heuristical warning is the best one can
hope for when taking the address alone.
The standard says quite clearly: "The result of the unary &
operator is a pointer to its operand. The operand shall be an
lvalue or a qualified-id." (The "qualified-id" is for pointers
to members.) This is taken almost directly from C: "The operand
of the unary & operator shall be either a function designator,
the result of a [] or unary * operator, or an lvalue that
designates an object that is not a bit-field and is not declared
with the register storage-class specifier." (This is taken from
C99, which is the only C standard which I have available here.
"result of a [] or unary * operator" was definitely not present
in C90; for the rest, however, the text is basically unchanged
from C90, and if memory serves me right, K&R C.)

In sum, this has never, ever been legal, and I can't see the
slightest reason for a compiler to accept it. Interestingly
enough, in both Sun CC and g++, it actually depends on the type:
both compilers treat something like:
int* p = foo() ;
(where foo() returns an int) as an error, and SunCC behaves
differently depending on whether there is inheritance or a user
defined constructor. None of which makes any sense to me: it's
an error, it has always been an error, and there's not the
slightest justification for any compiler in the world to treat
it otherwise.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #5
Hello,

James Kanze wrote:
Bernd Strieder wrote:
>James Kanze wrote:
On Apr 24, 1:13 am, Vols <volunte...@gmail.comwrote:
class A{
public:
int x;
};
>class B : public A{
public:
int y;
};
>void foo()
{
A &a1 = B();
A *a2 = &B();
}
>what happen with those 'B()'. I've never seen this before.
Me neither. Both lines in foo() are illegal in C++, and require
a diagnostic. (Much to my surprise, g++ only generates a
warning on the second, and Sun CC doesn't complain about
either! Which is IMHO simply not acceptable. Particularly the
second, which has never been legal C++.)
>Can't follow that.

Can't follow what? That it's illegal, or that some compilers
accept it.
>All g++-3.3.6, 4.2.1, and 4.3.0 make the first line in foo an
error and the second a warning without any special settings.

According to the standard, both are errors. The first was
allowed in very early versions of C++; it was found to cause
problems, and was banned sometime in the late 1980's (before the
standardization effort even began). I can understand compilers
in the early 1990's only giving a warning (so as not to break
existing code); I can even understand a compiler today having
options which would only make it a warning. But silently
accepting it, as Sun CC did? Something's wrong.

The second takes the address of an lvalue. That's never been
legal, not since K&R C. I can't understand any compiler not
making it a hard error.

(Note that the first can be made legal with a user defined
conversion to an lvalue in the class, and the second can be made
legal with a user defined operator&. Neither are present in the
example, however.)
>The first line is the one that assigns reference to a
temporary to a non-const reference type, which cannot work.

Strictly speaking: neither line "assigns" anything. The first
line initializes a non-const reference with an rvalue; that's
forbidden by §8.5.3/5. The second takes the address of an
lvalue; that's forbidden by §5.3.1/2. (And it would also be an
initialization, rather than an assignment. Although in the case
of pointers, unlike references, the difference is neglible.)
>The second line seems to have the same problem with const
pointer and non-const pointer at first.
>liftim1.cc: In function ?void foo()?:
liftim1.cc:12: error: invalid initialization of non-const reference
of type ?A&? from a temporary of type ?B?
liftim1.cc:13: warning: taking address of temporary
>A temporary object is not a const object by definition if
there is no const in the declaration.

Which isn't really relevant here.
>The standard mandates that assigning a temorary to a non-const
reference is not allowed, but this decision is kind of
deliberate, because it would produce hard to detect errors
most of the time.

It's very deliberate, because it actually did produce hard to
detect errors a lot of times.
>But taking the pointer is not the same es taking a reference.
Using that pointer could be problematic, especially
dereferencing, but the heuristical warning is the best one can
hope for when taking the address alone.

The standard says quite clearly: "The result of the unary &
operator is a pointer to its operand. The operand shall be an
lvalue or a qualified-id." (The "qualified-id" is for pointers
to members.) This is taken almost directly from C: "The operand
of the unary & operator shall be either a function designator,
the result of a [] or unary * operator, or an lvalue that
designates an object that is not a bit-field and is not declared
with the register storage-class specifier." (This is taken from
C99, which is the only C standard which I have available here.
"result of a [] or unary * operator" was definitely not present
in C90; for the rest, however, the text is basically unchanged
from C90, and if memory serves me right, K&R C.)
That makes it clear. I have to admit that I never got the time to get
into the very details of C and C++ standards that much. But then again
it is again a deliberate decision. The operation that is always
possible on a returned object should be an ordinary copy constructor
taking a const reference. When calling that copy constructor defined in
another translation unit, in the general case a compiler has to handle
a pointer to that temporary non-lvalue, internally. So in fact that
pointer exists on a level below C++, and the compiler has some sensible
pointer for the unary & to return. Breaking the standard when allowing
it, is still out of question.

What do we do with this modification of the OP example

class A{
public:
A(const A&);
A(const A*); // commodity copy c'tor
A();
int x;
};

void foo()
{
A a1 = A(); // ok
A a2 = &A(); // error ?
}

When looking at the data at runtime, there would be two temporary A
objects and the copy c'tor would get the address of its object passed
to copy. The lifetime of the temporary ends after the assignment in
both cases. And most compilers are able to generate what we expect. IMO
there is a window where that pointer could be considered valid.

AFAIK C++ has even introduced some special rule to enlarge the lifetime
of a temporary when assigned to a const reference variable. So even
there has been some room of argument.

If a bug gets filed for the compilers, then it will probably be very low
priority, because that pointer is causing fatal errors with very high
probability, when stored and dereferenced later, which anybody using it
should have noticed, and at least g++ even produces a warning. And as
horribly as it seems, there might be legacy code out there relying on
the feature. That class A like above is a probable outcome of e.g.
former C programmer getting C++ programmer.

Bernd Strieder

Jun 27 '08 #6

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

Similar topics

92
by: Reed L. O'Brien | last post by:
I see rotor was removed for 2.4 and the docs say use an AES module provided separately... Is there a standard module that works alike or an AES module that works alike but with better encryption?...
140
by: Oliver Brausch | last post by:
Hello, have you ever heard about this MS-visual c compiler bug? look at the small prog: static int x=0; int bit32() { return ++x; }
25
by: Nitin Bhardwaj | last post by:
Well, i'm a relatively new into C( strictly speaking : well i'm a student and have been doing & studying C programming for the last 4 years).....and also a regular reader of "comp.lang.c" I...
53
by: Deniz Bahar | last post by:
I know the basic definition of a sequence point (point where all side effects guaranteed to be finished), but I am confused about this statement: "Between the previous and next sequence point an...
13
by: param | last post by:
The following C program segfaults on 64 bit Arch., but works fine on 32 bit. int main() { int* p; p = (int*)malloc(sizeof(int)); *p = 10; return 0; }
44
by: Viken Karaguesian | last post by:
Hello all, On occasion I want to open hyperlinks (images, etc.) in a new window. In the past, I've used target="_blank" to open the link in a new window. However, using the "target" attribute...
67
by: neilcancer | last post by:
i come from china,and i'm sorry that my english is very poor. now i'm studing data structure and i met some problem about c language. could you tell me what will happen after i use free()? i...
16
by: Mr. Ken | last post by:
Left shift by negative numbers, will I get 1/2? Thanks.
11
by: active | last post by:
If I install .NET Framework 3.0 what will happen to my VS2005 experience? Will it automatically use 3.0? Will I find new features available? Will the VS doc be updated? Thanks fir any...
8
by: Raistlin Majere | last post by:
at test.php is... <form action = "test1.php" method = "POST"> <p> <b>Interests:</b> <br> <input type = "Checkbox" name = "interests" value = "politics">Politics <input type = "Checkbox" name...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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: 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
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.