Connecting Tech Pros Worldwide Help | Site Map

Compiler warning on ostream operator,

Thomas Lenz
Guest
 
Posts: n/a
#1: Oct 1 '08
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::ostream& operator,(std::ostream& rhs_, std::ostream& (* arg_
(std::ostream&))
{ return (rhs_ << arg_);
}
template<class Tstd::ostream& operator,(std::ostream& 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::ostream& operator,(std::ostream&,
std::ostream& (*)(std::ostream&))« always evaluates both arguments
junk.cpp:9: Warning: user-defined »std::ostream& operator,(std::ostream&,
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

Bill Davy
Guest
 
Posts: n/a
#2: Oct 1 '08

re: Compiler warning on ostream operator,



"Thomas Lenz" <lenzth@gmx.dewrote in message
news:48e30e50$0$6617$9b4e6d93@newsspool3.arcor-online.net...
Quote:
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::ostream& operator,(std::ostream& rhs_, std::ostream& (* arg_
(std::ostream&))
{ return (rhs_ << arg_);
}
template<class Tstd::ostream& operator,(std::ostream& 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::ostream& operator,(std::ostream&,
std::ostream& (*)(std::ostream&))« always evaluates both arguments
junk.cpp:9: Warning: user-defined »std::ostream& operator,(std::ostream&,
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


James Kanze
Guest
 
Posts: n/a
#3: Oct 1 '08

re: Compiler warning on ostream operator,


On Oct 1, 7:44 am, Thomas Lenz <len...@gmx.dewrote:
Quote:
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.
Quote:
cout << "hello", "world", endl;
Quote:
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.
Quote:
#include <iostream>
using namespace std;
Quote:
inline std::ostream& operator,(std::ostream& rhs_, std::ostream& (* arg_
(std::ostream&))
{ return (rhs_ << arg_);}
Quote:
template<class Tstd::ostream& operator,(std::ostream& rhs_, T arg_) {
return (rhs_ << ' ' << arg_); }
Quote:
int main()
{ cout << "hello", "world", endl;
}
Quote:
When I compile with the Weffc++ option, i get the warnings:
Quote:
junk.cpp:5: Warning: user-defined »std::ostream& operator,(std::ostream&,
std::ostream& (*)(std::ostream&))« always evaluates both arguments
junk.cpp:9: Warning: user-defined »std::ostream& operator,(std::ostream&,
T)« always evaluates both arguments
Quote:
Why?
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).
Quote:
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.

--
James Kanze (GABI Software) email:james.kanze@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
Thomas Lenz
Guest
 
Posts: n/a
#4: Oct 1 '08

re: Compiler warning on ostream operator,


am Mittwoch 01 Oktober 2008 11:48 schrieb James Kanze:
Quote:
On Oct 1, 7:44 am, Thomas Lenz <len...@gmx.dewrote:
Quote:
>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.
>
Quote:
> cout << "hello", "world", endl;
>
Quote:
>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.

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

Quote:
>
Quote:
>#include <iostream>
>using namespace std;
>
Quote:
>inline std::ostream& operator,(std::ostream& rhs_, std::ostream& (* arg_
>(std::ostream&))
>{ return (rhs_ << arg_);}
>
Quote:
>template<class Tstd::ostream& operator,(std::ostream& rhs_, T arg_) {
>return (rhs_ << ' ' << arg_); }
>
Quote:
>int main()
>{ cout << "hello", "world", endl;
>}
>
Quote:
>When I compile with the Weffc++ option, i get the warnings:
>
Quote:
>junk.cpp:5: Warning: user-defined »std::ostream& operator,(std::ostream&,
>std::ostream& (*)(std::ostream&))« always evaluates both arguments
>junk.cpp:9: Warning: user-defined »std::ostream& operator,(std::ostream&,
>T)« always evaluates both arguments
>
Quote:
>Why?
>
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.

Quote:
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).
>
Quote:
>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.
>
ok, i got it. Thanks again

Closed Thread