Compiler warning on ostream operator,

T

Thomas Lenz

The code below should allow to use a comma instead of << with ostreams and
include a space between two operands when comma is used. e.g.

cout << "hello", "world", endl;

should print the line "hello world".


#include <iostream>
using namespace std;

inline std::eek:stream& operator,(std::eek:stream& rhs_, std::eek:stream& (* arg_
(std::eek:stream&))
{ return (rhs_ << arg_);
}
template<class T> std::eek:stream& operator,(std::eek:stream& rhs_, T arg_) {
return (rhs_ << ' ' << arg_); }

int main()
{ cout << "hello", "world", endl;
}


When I compile with the Weffc++ option, i get the warnings:

junk.cpp:5: Warning: user-defined »std::eek:stream& operator,(std::eek:stream&,
std::eek:stream& (*)(std::eek:stream&))« always evaluates both arguments
junk.cpp:9: Warning: user-defined »std::eek:stream& operator,(std::eek:stream&,
T)« always evaluates both arguments


Why? I mean, of course the operator evaluates both arguments, that's what
they are for. BTW the code works fine; I'm just confused by these warnings.
I didn't find anything in the effective c++ books that could throw some
light on this. Can you?

Thanks,
Thomas
 
B

Bill Davy

Thomas Lenz said:
The code below should allow to use a comma instead of << with ostreams and
include a space between two operands when comma is used. e.g.

cout << "hello", "world", endl;

should print the line "hello world".


#include <iostream>
using namespace std;

inline std::eek:stream& operator,(std::eek:stream& rhs_, std::eek:stream& (* arg_
(std::eek:stream&))
{ return (rhs_ << arg_);
}
template<class T> std::eek:stream& operator,(std::eek:stream& rhs_, T arg_) {
return (rhs_ << ' ' << arg_); }

int main()
{ cout << "hello", "world", endl;
}


When I compile with the Weffc++ option, i get the warnings:

junk.cpp:5: Warning: user-defined »std::eek:stream& operator,(std::eek:stream&,
std::eek:stream& (*)(std::eek:stream&))« always evaluates both arguments
junk.cpp:9: Warning: user-defined »std::eek:stream& operator,(std::eek:stream&,
T)« always evaluates both arguments


Why? I mean, of course the operator evaluates both arguments, that's what
they are for. BTW the code works fine; I'm just confused by these
warnings.
I didn't find anything in the effective c++ books that could throw some
light on this. Can you?

Thanks,
Thomas

I think you should look up the comma (',') operator.

Bill
 
J

James Kanze

The code below should allow to use a comma instead of << with
ostreams and include a space between two operands when comma
is used. e.g.
cout << "hello", "world", endl;
should print the line "hello world".

Why? Have you overloaded the comma operator to do this? If so,
it's obfuscation; the classical idiom is:

std::cout << "hello" << ' ' << "world" << std::endl ;

And when there's a classical idiom, overloading operators to use
a different syntax is obfuscation in the first degree.
#include <iostream>
using namespace std;
inline std::eek:stream& operator,(std::eek:stream& rhs_, std::eek:stream& (* arg_
(std::eek:stream&))
{ return (rhs_ << arg_);}
template<class T> std::eek:stream& operator,(std::eek:stream& rhs_, T arg_) {
return (rhs_ << ' ' << arg_); }
int main()
{ cout << "hello", "world", endl;
}
When I compile with the Weffc++ option, i get the warnings:
junk.cpp:5: Warning: user-defined »std::eek:stream& operator,(std::eek:stream&,
std::eek:stream& (*)(std::eek:stream&))« always evaluates both arguments
junk.cpp:9: Warning: user-defined »std::eek:stream& operator,(std::eek:stream&,
T)« always evaluates both arguments

Well, the message is confusing. Of course, the operator, always
evaluates both arguments. The message looks more like it was
meant for && and || (where user defined operators always
evaluate both arguments, but the built-in operators
short-circuit). But overloading the comma operator like this is
*not* a good idea. Overloading the comma operator in general is
not a good idea (and is forbidden in most coding guidelines).
I mean, of course the operator evaluates both arguments,
that's what they are for. BTW the code works fine; I'm just
confused by these warnings. I didn't find anything in the
effective c++ books that could throw some light on this. Can
you?

Well, if the message had said something about the operator not
introducing a sequence point (when the built-in operator does),
it would make sense. Or simply if it said that this could
silently change the meaning of working code.

One of the rare legitimate uses I can think of the comma
operator is for conditionally inserting debugging output, in
conjunction with macros. Something like:

#ifdef ACTIVATE_DEBUGGING
#define TRACE( x ) std::cerr << x
#else
#define TRACE( x ) (void)0
#endif

class C
{
public:
C( int i ) : myValue( TRACE( i ), i ) {}
// ...
} ;

If your operator is defined before this header is included,
you're going to get some very surprising results when tracing is
turned on.
 
T

Thomas Lenz

am Mittwoch 01 Oktober 2008 11:48 schrieb James Kanze:
Why? Have you overloaded the comma operator to do this? If so,
it's obfuscation; the classical idiom is:

std::cout << "hello" << ' ' << "world" << std::endl ;

And when there's a classical idiom, overloading operators to use
a different syntax is obfuscation in the first degree.


It's minimized code to highlight my comma operator question. I'm not going
to do this in real life.

Well, the message is confusing. Of course, the operator, always
evaluates both arguments. The message looks more like it was
meant for && and || (where user defined operators always
evaluate both arguments, but the built-in operators
short-circuit).


That's a very plausible explanation. Thank you for pointing this out.

But overloading the comma operator like this is
*not* a good idea. Overloading the comma operator in general is
not a good idea (and is forbidden in most coding guidelines).


Well, if the message had said something about the operator not
introducing a sequence point (when the built-in operator does),
it would make sense. Or simply if it said that this could
silently change the meaning of working code.

One of the rare legitimate uses I can think of the comma
operator is for conditionally inserting debugging output, in
conjunction with macros. Something like:

#ifdef ACTIVATE_DEBUGGING
#define TRACE( x ) std::cerr << x
#else
#define TRACE( x ) (void)0
#endif

class C
{
public:
C( int i ) : myValue( TRACE( i ), i ) {}
// ...
} ;

If your operator is defined before this header is included,
you're going to get some very surprising results when tracing is
turned on.

ok, i got it. Thanks again
 

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,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top