[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Compiler warning on ostream operator,

Thomas Lenz

10/1/2008 5:45:00 AM

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 T> std::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

3 Answers

Bill Davy

10/1/2008 6:47:00 AM

0


"Thomas Lenz" <lenzth@gmx.de> wrote in message
news:48e30e50$0$6617$9b4e6d93@newsspool3.arcor-online.net...
> 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 T> std::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

10/1/2008 9:49:00 AM

0

On Oct 1, 7:44 am, Thomas Lenz <len...@gmx.de> wrote:
> 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::ostream& operator,(std::ostream& rhs_, std::ostream& (* arg_
> (std::ostream&))
> { return (rhs_ << arg_);}

> template<class T> std::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?

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.

--
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

10/1/2008 12:46:00 PM

0

am Mittwoch 01 Oktober 2008 11:48 schrieb James Kanze:

> On Oct 1, 7:44 am, Thomas Lenz <len...@gmx.de> wrote:
>> 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.


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


>
>> #include <iostream>
>> using namespace std;
>
>> inline std::ostream& operator,(std::ostream& rhs_, std::ostream& (* arg_
>> (std::ostream&))
>> { return (rhs_ << arg_);}
>
>> template<class T> std::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?
>
> 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).
>
>> 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