473,672 Members | 2,539 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

wrong compiler warning?

Hi all,

I've a problem. The code that follows creates a warning in both gcc and
visual c++. However, I think it's correct: basically, there is a
function that return an object of a derived class, that's bounded to a
base class reference to delay the destruction of the actual object to
the end of the reference scope. Actually, I don't use the reference: the
code that matters is in the destructor, and I want it to be executed at
the end of the method.

Really strange, both the compilers warn me about the "useless"
reference... I'm feared that if the compilers "think" that the reference
is useless, they could try some dangerous optimization...

Here follows a simple example:
#include <iostream>

class Base
{
public:
Base() { std::cout << "Base\n"; std::cout.flush (); }
virtual ~Base() { std::cout << "~Base\n"; std::cout.flush (); }

virtual char* Name() const { return "Base"; }
};

class Derived : public Base
{
public:
Derived() { std::cout << "Derived\n" ; std::cout.flush (); }
~Derived() { std::cout << "~Derived\n "; std::cout.flush (); }

char* Name() const { return "Derived"; }
};

Derived foo()
{
std::cout << "foo function\n"; std::cout.flush ();
return Derived();
}

int main()
{
std::cout << "begin of the program\n"; std::cout.flush ();
const Base& obj = foo();
std::cout << "this is the program body\n"; std::cout.flush ();

return 0;
}


Thank you,

Zeppe
Sep 11 '06 #1
11 2015
zeppe wrote:
I've a problem. The code that follows creates a warning in both gcc
and visual c++. However, I think it's correct: basically, there is a
function that return an object of a derived class, that's bounded to a
base class reference to delay the destruction of the actual object to
the end of the reference scope. Actually, I don't use the reference:
the code that matters is in the destructor, and I want it to be
executed at the end of the method.
Just declare an object instead of a reference.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 11 '06 #2
Victor Bazarov wrote:
zeppe wrote:
>I've a problem. The code that follows creates a warning in both gcc
and visual c++. However, I think it's correct: basically, there is a
function that return an object of a derived class, that's bounded to a
base class reference to delay the destruction of the actual object to
the end of the reference scope. Actually, I don't use the reference:
the code that matters is in the destructor, and I want it to be
executed at the end of the method.

Just declare an object instead of a reference.

V
if i declare an object instead of a reference i lose the type polymorphism.

i.e., output with reference:

begin of the program
foo function
Base
Derived
this is the program body
~Derived
~Base
output with object:

begin of the program
foo function
Base
Derived
~Derived
~Base
this is the program body
~Base
Of course in the real world i don't know that foo returns Derived, so
the object should be Base.

Zeppe
Sep 11 '06 #3
zeppe wrote:
Victor Bazarov wrote:
>zeppe wrote:
>>I've a problem. The code that follows creates a warning in both gcc
and visual c++. However, I think it's correct: basically, there is a
function that return an object of a derived class, that's bounded
to a base class reference to delay the destruction of the actual
object to the end of the reference scope. Actually, I don't use the
reference: the code that matters is in the destructor, and I want
it to be executed at the end of the method.

Just declare an object instead of a reference.

V

if i declare an object instead of a reference i lose the type
polymorphism.
What polymorphism? Polymorphism in deleting it? D-tors cannot call
virtual functions polymorphically . If you want to rely on proper
d-tor to be called, you probably need to use 'auto_ptr' and return
a pointer from your function, not a temporary.
i.e., output with reference:

[..]

Of course in the real world i don't know that foo returns Derived, so
the object should be Base.
Huh?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 11 '06 #4
Victor Bazarov wrote:
>if i declare an object instead of a reference i lose the type
polymorphism .

What polymorphism? Polymorphism in deleting it? D-tors cannot call
virtual functions polymorphically . If you want to rely on proper
d-tor to be called, you probably need to use 'auto_ptr' and return
a pointer from your function, not a temporary.
I don't see the difference. If I have

class Derived: public Base

and i return a temporary Derived, and I attach a reference const Base&,
I have polymrphism in descructor, that is, i delay the Temporary
destruction until the end of the reference lifetime.
>>
Of course in the real world i don't know that foo returns Derived, so
the object should be Base.

Huh?
I have

Derived foo();

I can solve writing:

Derived obj = foo();

but if I have a more complex sitation and i don't know that foo returns
a Derived, i can only rely in auto_ptr or in references.

Bye,

Zeppe
Sep 11 '06 #5
zeppe wrote:
[..]
I have

Derived foo();

I can solve writing:

Derived obj = foo();

but if I have a more complex sitation and i don't know that foo
returns a Derived, i can only rely in auto_ptr or in references.
Your 'foo' returns _an_object_. How can you not know what it is?
Your 'foo' doesn't return a reference, in which case you could claim
the ability to use polymorphism. If it's slicing you're trying to
avoid, your 'foo' has already sliced everything, binding a reference
to it is pointless.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 11 '06 #6
Victor Bazarov ha scritto:
Your 'foo' returns _an_object_. How can you not know what it is?
Your 'foo' doesn't return a reference, in which case you could claim
the ability to use polymorphism.
You are right. But actually, in a more complex example, the real object
could be somewhat hidden, for example with traits. Consider the
following example (a bit longer):

#include <iostream>

class Base
{
public:
Base() { std::cout << "Base\n"; std::cout.flush (); }
virtual ~Base() { std::cout << "~Base\n"; std::cout.flush (); }

virtual char* Name() const { return "Base"; }
};

class Derived : public Base
{
public:
Derived() { std::cout << "Derived\n" ; std::cout.flush (); }
~Derived() { std::cout << "~Derived\n "; std::cout.flush (); }

char* Name() const { return "Derived"; }
};

template <class T>
struct Bar_traits
{
typedef Base ret_type;
};
template <>
struct Bar_traits<int>
{
typedef Derived ret_type;
};

template <class T>
typename Bar_traits<T>:: ret_type foo(){
std::cout << "foo function\n"; std::cout.flush ();
return typename Bar_traits<T>:: ret_type();
}
int main()
{
std::cout << "begin of the program\n"; std::cout.flush ();
const Base& obj = foo<int>();
std::cout << "this is the program body\n"; std::cout.flush ();

return 0;
}

I know I could declare a traits, i.e. Bar_traits<into bj = foo<int>();
but is not always clean to do so. I was asking if binding the return
temporary type polimorphically on a reference is allowed.
If it's slicing you're trying to
avoid, your 'foo' has already sliced everything, binding a reference
to it is pointless.
Why has sliced? I returned a 'Derived', that's all. Binding a 'Derived'
with a 'Base' reference it's illegal (I don't think)? It produces slicing?

Thank you for answers.

Zeppe
Sep 12 '06 #7
zeppe wrote:
Victor Bazarov ha scritto:
>Your 'foo' returns _an_object_. How can you not know what it is?
Your 'foo' doesn't return a reference, in which case you could claim
the ability to use polymorphism.

You are right. But actually, in a more complex example, the real
object could be somewhat hidden, for example with traits. Consider the
following example (a bit longer):

#include <iostream>

class Base
{
public:
Base() { std::cout << "Base\n"; std::cout.flush (); }
virtual ~Base() { std::cout << "~Base\n"; std::cout.flush (); }

virtual char* Name() const { return "Base"; }
};

class Derived : public Base
{
public:
Derived() { std::cout << "Derived\n" ; std::cout.flush (); }
~Derived() { std::cout << "~Derived\n "; std::cout.flush (); }

char* Name() const { return "Derived"; }
};

template <class T>
struct Bar_traits
{
typedef Base ret_type;
};
template <>
struct Bar_traits<int>
{
typedef Derived ret_type;
};

template <class T>
typename Bar_traits<T>:: ret_type foo(){
std::cout << "foo function\n"; std::cout.flush ();
return typename Bar_traits<T>:: ret_type();
}
int main()
{
std::cout << "begin of the program\n"; std::cout.flush ();
const Base& obj = foo<int>();
std::cout << "this is the program body\n"; std::cout.flush ();

return 0;
}

I know I could declare a traits, i.e. Bar_traits<into bj =
foo<int>(); but is not always clean to do so.
Not always? What are you talking about?

All you need to do is to use the function itself to introduce the
type. With introduction of TR1 it's going to be very easy, AFAIUI:

std::tr1::resul t_of<foo<int obj = foo<int>();

Meanwhile you can probably use 'Boost'.
I was asking if binding
the return temporary type polimorphically on a reference is allowed.
Yes, it's allowed. That's why you have a *warning* and not an *error*
in your program. Simply ignore your warning if you don't want to make
changes to have your program compile cleanly.
>If it's slicing you're trying to
avoid, your 'foo' has already sliced everything, binding a reference
to it is pointless.

Why has sliced? I returned a 'Derived', that's all. Binding a
'Derived' with a 'Base' reference it's illegal (I don't think)? It
produces slicing?
No. Binding a reference does not introduce slicing. Read what I wrote
more carefully, and think about it before replying.

Now, think about it. Next time somebody makes your 'foo<int>' return
a type that is not a descendant of 'Base'. What do you do then? That
is why you shouldn't stop mid-stream when making your stuff generic.
If your function relies on some traits template to return a proper
object type, use the same traits to declare the receiving object.

Is there anything else here that needs clarification?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 12 '06 #8
Victor Bazarov ha scritto:
>I know I could declare a traits, i.e. Bar_traits<into bj =
foo<int>(); but is not always clean to do so.

Not always? What are you talking about?
Bacause sometimes the template matching is automatic and based on the
function argument list, and the template arguments are many, and I don't
want to write it explicitely, because is useless, dirty and error prone.
Simply that.
All you need to do is to use the function itself to introduce the
type. With introduction of TR1 it's going to be very easy, AFAIUI:

std::tr1::resul t_of<foo<int obj = foo<int>();

Meanwhile you can probably use 'Boost'.
Thank you for the suggestion. Actually, I could use traits in a similar
way, but I would avoid to explicitely list the template arguments.
>>If it's slicing you're trying to
avoid, your 'foo' has already sliced everything, binding a reference
to it is pointless.
Why has sliced? I returned a 'Derived', that's all. Binding a
'Derived' with a 'Base' reference it's illegal (I don't think)? It
produces slicing?

No. Binding a reference does not introduce slicing. Read what I wrote
more carefully, and think about it before replying.
Yes, I answered like that because I can't understand where the slicing
could take place in my original program. Since it don't seem to me that
foo could cause slicing (maybe i don't have yet well understood your
initial comment), I was asking if some other piece of code were illegal.
Now, think about it. Next time somebody makes your 'foo<int>' return
a type that is not a descendant of 'Base'. What do you do then?
Compile-time error? I want the reference to the correct object because I
want the correct destructor to be called at the end of the reference
variable life, but I *do* want that the return object of the foo method
is derived from a certain type (i.e., sometimes I need to use some
'Base' methods).

That
is why you shouldn't stop mid-stream when making your stuff generic.
If your function relies on some traits template to return a proper
object type, use the same traits to declare the receiving object.

Is there anything else here that needs clarification?
For the reasons above, I want to know that the returned object is
derived from Base, I don't want the stuff to be too generic.

End of all, I still don't understand why the compiler gives me the error
that the variable isn't used. It *is* (in the destructor), and I don't
think my code is unsafe.

Thank you for your patience.

Zeppe
Sep 12 '06 #9
zeppe wrote:
[..]
End of all, I still don't understand why the compiler gives me the
error that the variable isn't used.
Uh... It doesn't give you the *error*. It gives you a *warning*.
Your code is not ill-formed. Just ignore the warning, will you? Just
let it go. Let it be. Forgedaboudit. Disable it using compiler-
specific means (like a command-line switch or a pragma), if you are
startled by its appearing in your compiler output.

It is not a common idiom to return an object, bind it to a reference
and wait till the reference goes out of scope. Yes, it does prolong
the lifetime of the temporary. It's just not used so often, that's
why the compiler writers decided to let you know that you might be
missing something, probably. I am not sure I need to explain to you
the merit of compiler *warnings*, but here is an example:

Blah blah1, &blah2 = somefunction();

blah1.foo();
blah1.foo(); // inteded to say 'blah2.foo()', but made a typo

Here, the compiler warns you of 'blah2' being unused. And it is
unused, for all intents and purposes. Make it const, and it does
change something, but not enough to justify dropping the warning.

Again, I feel a bit strange trying to justify a compiler warning to
you. Contact your compiler makers if you feel that a warning is not
appropriate in that case, and see what they tell you.
It *is* (in the destructor), and
I don't think my code is unsafe.
What makes you think that warning has anything to do with safety?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 12 '06 #10

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

Similar topics

1
3174
by: Hafeez | last post by:
I am having real trouble compiling this code http://www.cs.wisc.edu/~vganti/birchcode/codeHier/AttrProj.tgz The attachment shows errors when compiled using the current version of g++ in a i386-pc-solaris2.9. Seeing reference to gcc-2.7.2 in the Makefile of the code, I downloaded it and compiled in my home directory. Then changed the referenes of LIBDIR and INCLUDES to this installation .and ran with g++ for 2.7.2 then there are still...
2
2163
by: atv | last post by:
Hi, is there something wrong with this code? It seems that it crashes at the else { clause, when allocating a second record. Excuse for the indentation, the g_warnings are from gtk. Also, i'm using 2 pointers in the struct, which consists of 3 ints, and 2 pointers, which i give 256 bytes each. Much to much ofcourse, but it's just testcode. The code doesn't even reach the g_warning in the { code.
30
1727
by: Philippe Bertrand | last post by:
Is this a bug in the C# compiler or CLR runtime? enum MyEnum { ZERO = 0, ONE = 1, TWO = 2 } class Foo { public Foo(string,object) { ... } public Foo(string,MyEnum) { ... } } Foo f = new Foo("", 0); // Uses Foo(string,MyEnum) constructor instead of Foo(string,object)
34
4856
by: Bob | last post by:
Hi, The compiler gives Warning 96 Variable 'cmdSource' is used before it has been assigned a value. A null reference exception could result at runtime. Dim cmdSource as SQlClient.SQLDataReader Try Set up the database read and do it. Catch ex as system.exception exception stuff here Finally
83
3935
by: Anonymous | last post by:
Came across some code summarized as follows: char const* MyClass::errToText(int err) const { switch (err) { case 0: return "No error"; case 1: return "Not enough"; case 2: return "Too much"; default: return "Unknown error";
15
9023
by: robert maas, see http://tinyurl.com/uh3t | last post by:
Here's the source: #include <stdio.h> #include <errno.h> main () { char* str = "9999999999"; long long int llin; char* endptr; /* Set by strtoll */ int nch; errno = 0; llin = strtoll(str, &endptr, 10); printf("errno=%d\n", errno);
30
508
by: Bill Reid | last post by:
#define MAX_VALUES 64 typedef struct { unsigned value_1; double value_2; double value_3; double value_4; } VALUES; typedef struct {
0
1481
by: Grant Edwards | last post by:
I've got a system where I try to install extensions using /usr/local/bin/python setup.py install But, it fails when it tries to use a non-existant compiler path and specs file. I suspect it's trying to use the compieler that was used to build /usr/bin/python. How do I get it to use the compiler settings that were used for /usr/local/bin/python?
10
2051
by: questions | last post by:
# include <stdio.h> # include <math.h> int main() { long int x,y; printf("enter an integer\n"); scanf("%d",&x); y=x%pow(10,3);
0
8404
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8828
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8608
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8680
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7446
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5705
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4227
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2819
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1816
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.