Invoking methods on objects returned from functions

E

Elven

Hi!

I've been trying to figure this out, but can't seem to find an answer.
Most likely it's some weird bug in my code, but since I don't have
access to the Standard, I wanted to cover my bases.. basically the
situation is that I'm writing a logging facility, class Log. Instances
of the class can be invoked to read a message by using the method
Read() that enables the overloaded op<<. The trick is, Read() does not
necessarily return the Log reference (*this), but a reference to
another object, a Logstream. So the code looks something like

logger.Read() << "This is to be " << "logged.";
return 0;

Now, the problem is: if I return *this in Read(), everything works
fine. However, if I return a Logstream&, the program skips directly to
the return instruction. Even if I disable the op<< for Logstream,
there's no complaint, which suggests that op<< isn't applied to the
result of logger() -but when returning a Log object it is, with all
other code the exact same.

So, the question is: does anyone know of anything in the Standard that
causes this, or is there just a bug in the program -and if so, any
ideas where to look? I'll post followups if I figure it out.
 
J

Jonathan Mcdougall

I've been trying to figure this out, but can't seem to find an answer.
Most likely it's some weird bug in my code

Most likely, yes :)
, but since I don't have
access to the Standard, I wanted to cover my bases.. basically the
situation is that I'm writing a logging facility, class Log.

Please, try to post some code next time.
Instances
of the class can be invoked to read a message by using the method
Read() that enables the overloaded op<<.

A method (btw, there is no such thing in C++, it is called "member
function". Whatever) cannot "enable the overloaded op<<". A function
overloads another.
The trick is, Read() does not
necessarily return the Log reference (*this), but a reference to
another object, a Logstream. So the code looks something like

What is Logstream ? Is there an overloaded operator<< for it? If not, does
it inherit from Log? If Logstream is an independent class with no
overloaded operator<< and if no operator<<() can be applied to it, you
should have gotten a compilation error.
logger.Read() << "This is to be " << "logged.";
return 0;
Now, the problem is: if I return *this in Read(), everything works
fine. However, if I return a Logstream&, the program skips directly to
the return instruction.

That is impossible. The program cannot "skip" a statement because of a
return value.
Even if I disable the op<< for Logstream,
there's no complaint, which suggests that op<< isn't applied to the
result of logger() -but when returning a Log object it is, with all
other code the exact same.

That is weird. It means the compiler found another operator<<() somewhere
which is appropriatly overloaded and has a higher precedence than yours.
So, the question is: does anyone know of anything in the Standard that
causes this,
Nope.

or is there just a bug in the program -and if so, any
ideas where to look?

Line 27. Whenever you got something not working, look around line 27, there
is *always* something wrong there.
I'll post followups if I figure it out.

And I hope you'll post followups to show us some code.


Jonathan
 
E

e

Please, try to post some code next time.

And I hope you'll post followups to show us some code.

Well, the app is quite large. I thought that someone might be able to
say offhand whether there was something wrong with the concept. In any
case, it looks like it's definitely a problem somewhere in the depths
of the program.. This is the file I'm using to test (well,
paraphrased):

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

#include "log.h"
#include "logcontrol.h"
#include "logstream.h"

using namespace admin;
using namespace admin::log;

int main()
{
// Dummy
Logstream<int, std::eek:stringstream> info(ctl::NORMAL);

// Dummy reference..
Logstream<int, std::eek:stringstream> & r_info = info;

// Log object
// Log<> logger( /* Parameters */ );

// Tests
info << "This is some dummy text.. " << "More text.";

r_info << "This is some dummy text.. " << "More text.";

// logger.Read() << "Text." << "More text.";

return 0;
}
-----------------------------------------------------------------------------------------------------------

I did some more testing.. notice the commented-out line declaring the
Log object. This program compiles and runs as expected (I'm running
it in a debugger and I see the calls to operator<<), the Logstream
gathers the arguments both directly and via the reference. However, if
I uncomment the line declaring logger, both tests fail to execute. The
debugger shows that execution enters and skips the two first checks
and when it hits logger.Read(), it executes the member function :))
and eventually returns a Logstream reference. The next thing that
happens is the return instruction (i.e. there are no calls to
operator<<.)

I'm stumped. A compiler problem? Let me know if you know of anything
that could possibly cause the problem in the language spec -I'll
gladly post additional code if necessary (please point out which part
you need it of), but I'd rather avoid it if possible.

Ta.
 
P

Peter van Merkerk

I did some more testing.. notice the commented-out line declaring the
Log object. This program compiles and runs as expected (I'm running
it in a debugger and I see the calls to operator<<), the Logstream
gathers the arguments both directly and via the reference. However, if
I uncomment the line declaring logger, both tests fail to execute. The
debugger shows that execution enters and skips the two first checks
and when it hits logger.Read(), it executes the member function :))
and eventually returns a Logstream reference. The next thing that
happens is the return instruction (i.e. there are no calls to
operator<<.)

I'm stumped. A compiler problem? Let me know if you know of anything
that could possibly cause the problem in the language spec

Who knows? You have the all code in front of you and you can't tell what
is wrong. The people in this group don't know what happens inside Log
and Logstream; how are they supposed to know what is wrong? Post minimal
code (preferably less than 50 lines), yet complete (that is
compilable), code that demonstrates the problem you are having. Chances
are that when trimming down your code to produce a example you will find
the problem.
-I'll
gladly post additional code if necessary (please point out which part
you need it of), but I'd rather avoid it if possible.

Without the right information nobody will be able to help you or even
make a wild guess.
 
E

e

Who knows? You have the all code in front of you and you can't tell what
is wrong. The people in this group don't know what happens inside Log
and Logstream; how are they supposed to know what is wrong? Post minimal
code (preferably less than 50 lines), yet complete (that is
compilable), code that demonstrates the problem you are having. Chances
are that when trimming down your code to produce a example you will find
the problem.

Unfortunately that won't be possible. Looking at the code, there's
approximately 500 lines for a minimal compilable unit (lots of
dependencies), so it's not feasible to reproduce it as is. I'll see
what I can do.

I was just wondering if anyone knew how it would be possible for the
code to skip instructions because of the uncommented line -not crash,
or report an error, but skip instructions that it is not a part of
entirely. To me it seems that this is a problem with the compiler and
my code, not anything (legal) in the spec.

Thanks anyway!
 
J

Jonathan Mcdougall

This program compiles and runs as expected (I'm running
it in a debugger and I see the calls to operator<<), the Logstream
gathers the arguments both directly and via the reference. However, if
I uncomment the line declaring logger, both tests fail to execute. The
debugger shows that execution enters and skips the two first checks
and when it hits logger.Read(), it executes the member function :))
and eventually returns a Logstream reference. The next thing that
happens is the return instruction (i.e. there are no calls to
operator<<.)

If

int main()
{
a_logstream_object << "hey";
}

works (with a call to operator<<() ) and

Logstream &f()
{
return a_logstream_object;
}

int main()
{
f() << "hey";
}

does not (that is, operator<<() is not called _at all_), there is a serious
problem with the compiler. Change it.

If it does, back to your program, check the Read() member function. Does it
copy the Logstream? If yes, is it ok to copy it?

If not, try to access the Logstream object directly (it probably is a
private member of Logger; make it public and use it directly). Does that
Logstream object work? If not, the problem is there. If yes, the Read()
member function is the problem.

If the Logstream object, used directly, does not work, make sure it is
created and used correctly.

These are _very_ wild guesses, but that is the best I can do. Try to make
the code as complete as possible and post it on a website or something if
you really need help.


Jonathan
 
E

e

-- there is a serious
problem with the compiler. Change it.

I did. Intel compiles fine, as actually did g++ with certain (higher)
optimization levels. I rebuilt gcc and everything works now. I'll try
and find the problem and post in their bug lists :) Thanks, folks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top